package cn.iocoder.yudao.module.system.service.gugu;

import cn.iocoder.yudao.module.system.controller.admin.gugu.gugu.CollegeEnrollmentPlanInfo;
import cn.iocoder.yudao.module.system.controller.admin.gugu.gugu.MajorAdmissionInfo;
import cn.iocoder.yudao.module.system.controller.admin.gugu.gugu.UserProfileInfo;
import cn.iocoder.yudao.module.system.controller.admin.gugu.vo.StructuredUserDataReqVO;
import cn.iocoder.yudao.module.system.controller.admin.gugu.vo.DirectParamsGroupRespVO;
import cn.iocoder.yudao.module.system.controller.admin.gugu.vo.SuitableMajorsRespVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.dal.dataobject.college.CollegeDO;
import cn.iocoder.yudao.module.system.dal.mysql.college.CollegeMapper;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.dal.dataobject.collegeenrollmentplan.CollegeEnrollmentPlanDO;
import cn.iocoder.yudao.module.system.dal.dataobject.gugu.MajorAdmissionDO;
import cn.iocoder.yudao.module.system.dal.mysql.collegeenrollmentplan.CollegeEnrollmentPlanMapper;
import cn.iocoder.yudao.module.system.dal.mysql.gugu.MajorAdmissionMapper;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.system.util.ChineseSegmentationUtil;
import cn.iocoder.yudao.module.system.util.SubjectSelectionUtils;
import org.springframework.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 用户个人信息服务
 */
@Service
@EnableAsync
@Slf4j
public class UserProfileService {

    // 性能优化配置常量
    private static final int LARGE_DATA_THRESHOLD = 10000; // 大数据量阈值
    private static final int BATCH_SIZE = 5000; // 批处理大小
    private static final int MAX_DATA_WARNING_THRESHOLD = 15000; // 最大数据量警告阈值

    // 创建线程池，用于并行查询历史数据
    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    @Resource
    private MajorAdmissionService majorAdmissionService;

    @Resource
    private CollegeEnrollmentPlanService collegeEnrollmentPlanService;

    @Resource
    MajorAdmissionMapper majorAdmissionMapper;

    @Resource
    private CollegeEnrollmentPlanMapper collegeEnrollmentPlanMapper;

    @Resource
    private AdminUserService adminUserService;

    @Resource
    private CollegeMapper collegeMapper;

    /**
     * 在服务关闭时关闭线程池
     */
    @PreDestroy
    public void shutdown() {
        // 尝试优雅地关闭线程池
        executorService.shutdown();
        try {
            // 等待所有任务完成，最多等待5秒
            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                // 如果超时，强制关闭
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            // 如果等待被中断，强制关闭
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 从用户输入中提取个人信息
     * @param userInput 用户输入的文本
     * @return 提取的用户个人信息
     */
    public UserProfileInfo extractUserProfile(String userInput) {
        UserProfileInfo profile = new UserProfileInfo();

        // 提取省份
        Pattern provincePattern = Pattern.compile("([\u4e00-\u9fa5]+)(省|市|自治区)?\\d{4}年考生");
        Matcher provinceMatcher = provincePattern.matcher(userInput);
        if (provinceMatcher.find()) {
            profile.setProvince(provinceMatcher.group(1));
        }

        // 提取年份
        Pattern yearPattern = Pattern.compile("(\\d{4})年考生");
        Matcher yearMatcher = yearPattern.matcher(userInput);
        if (yearMatcher.find()) {
            profile.setYear(Integer.parseInt(yearMatcher.group(1)));
        }

        // 提取性别
        if (userInput.contains("男生")) {
            profile.setGender("男");
        } else if (userInput.contains("女生")) {
            profile.setGender("女");
        }

        // 提取选科
        List<String> subjects = new ArrayList<>();
        Pattern subjectPattern = Pattern.compile("选科是([^，。]+)");
        Matcher subjectMatcher = subjectPattern.matcher(userInput);
        if (subjectMatcher.find()) {
            String subjectsStr = subjectMatcher.group(1);
            String[] subjectArray = subjectsStr.split("、|，|,|\\s+");
            subjects.addAll(Arrays.asList(subjectArray));
        }
        profile.setSubjects(subjects);

        // 提取总分
        Pattern totalScorePattern = Pattern.compile("高考总分(\\d+)");
        Matcher totalScoreMatcher = totalScorePattern.matcher(userInput);
        if (totalScoreMatcher.find()) {
            profile.setTotalScore(Integer.parseInt(totalScoreMatcher.group(1)));
        }

        // 提取各科分数
//        Map<String, Integer> subjectScores = new HashMap<>();
//        Pattern subjectScorePattern = Pattern.compile("([^:：,，\\.。\\d]+):?：?(\\d+)");
//        Matcher subjectScoreMatcher = subjectScorePattern.matcher(userInput);
//        while (subjectScoreMatcher.find()) {
//            String subject = subjectScoreMatcher.group(1).trim();
//            Integer score = Integer.parseInt(subjectScoreMatcher.group(2));
//            subjectScores.put(subject, score);
//        }
//        profile.setSubjectScores(subjectScores);

        // 提取性格特点
        List<String> personalityTraits = new ArrayList<>();
        if (userInput.contains("性格内向")) {
            personalityTraits.add("内向");
        }
        if (userInput.contains("性格外向")) {
            personalityTraits.add("外向");
        }
        if (userInput.contains("学习能力强")) {
            personalityTraits.add("学习能力强");
        }
        if (userInput.contains("社交能力强")) {
            personalityTraits.add("社交能力强");
        }
        profile.setPersonalityTraits(personalityTraits);

        // 提取家庭年收入
        Pattern incomePattern = Pattern.compile("家庭年收入(\\d+)万到(\\d+)万");
        Matcher incomeMatcher = incomePattern.matcher(userInput);
        if (incomeMatcher.find()) {
            String lowerBound = incomeMatcher.group(1);
            String upperBound = incomeMatcher.group(2);
            profile.setFamilyIncome(lowerBound + "万-" + upperBound + "万");
        }

        // 提取毕业去向
        if (userInput.contains("大学毕业后会就业")) {
            profile.setGraduationPlan("就业");
        } else if (userInput.contains("大学毕业后会考研")) {
            profile.setGraduationPlan("考研");
        } else if (userInput.contains("大学毕业后会出国")) {
            profile.setGraduationPlan("出国");
        }

        // 提取感兴趣的专业类别
        List<String> interestedMajors = new ArrayList<>();
        Pattern majorPattern = Pattern.compile("对([^,，。]+)感兴趣");
        Matcher majorMatcher = majorPattern.matcher(userInput);
        if (majorMatcher.find()) {
            String majorsStr = majorMatcher.group(1);
            String[] majorArray = majorsStr.split("、|，|,|\\s+");
            interestedMajors.addAll(Arrays.asList(majorArray));
        }
        profile.setInterestedMajorCategories(interestedMajors);

        // 提取期望学校所在地
        Pattern locationPattern = Pattern.compile("想去的学校所在地：([^，。]+)");
        Matcher locationMatcher = locationPattern.matcher(userInput);
        if (locationMatcher.find()) {
            profile.setPreferredLocation(locationMatcher.group(1));
        }

        // 提取分数范围（格式：分数范围：537-547）
        Pattern scoreRangePattern = Pattern.compile("分数范围[：:]?(\\d+)[-－](\\d+)");
        Matcher scoreRangeMatcher = scoreRangePattern.matcher(userInput);
        if (scoreRangeMatcher.find()) {
            try {
                int minScore = Integer.parseInt(scoreRangeMatcher.group(1));
                int maxScore = Integer.parseInt(scoreRangeMatcher.group(2));
                profile.setMinScore(minScore);
                profile.setMaxScore(maxScore);
                log.info("从用户输入中解析到分数范围: {}-{}", minScore, maxScore);
            } catch (NumberFormatException e) {
                log.warn("解析分数范围失败: {}", scoreRangeMatcher.group(0));
            }
        } else {
            log.info("用户输入中未找到分数范围信息，将使用默认分数范围计算");
        }
        // 根据选科确定用户类型
        if (profile.getSubjects() != null && !profile.getSubjects().isEmpty()) {
            // 检查是否包含物理和历史，这两个是首选科目
            boolean hasPhysics = profile.getSubjects().stream().anyMatch(s -> s.contains("物理"));
            boolean hasHistory = profile.getSubjects().stream().anyMatch(s -> s.contains("历史"));

            String firstSubject = null;
            if (hasPhysics) {
                firstSubject = "物理";
            } else if (hasHistory) {
                firstSubject = "历史";
            }

            if (firstSubject != null) {
                String typeName = determineSubjectSelection(profile.getProvince(), firstSubject);
                profile.setTypeName(typeName);
                log.info("根据用户选科确定类型为: {}", typeName);
            }
        }

        return profile;
    }

    /**
     * 从结构化用户数据中提取个人信息
     * @param userAnswers 结构化的用户问答数据
     * @return 提取的用户个人信息
     */
    public UserProfileInfo extractUserProfileFromStructuredData(Map<String, StructuredUserDataReqVO.QuestionAnswer> userAnswers) {
        UserProfileInfo profile = new UserProfileInfo();

        try {
            // 1. 提取省份
            StructuredUserDataReqVO.QuestionAnswer provinceAnswer = userAnswers.get("1");
            if (provinceAnswer != null && provinceAnswer.getAnswer() != null) {
                profile.setProvince(provinceAnswer.getAnswer().toString());
            }

            // 2. 提取性别
            StructuredUserDataReqVO.QuestionAnswer genderAnswer = userAnswers.get("2");
            if (genderAnswer != null && genderAnswer.getAnswer() != null) {
                String genderStr = genderAnswer.getAnswer().toString();
                if (genderStr.contains("女")) {
                    profile.setGender("女");
                } else if (genderStr.contains("男")) {
                    profile.setGender("男");
                }
            }

            // 3. 提取选科
            StructuredUserDataReqVO.QuestionAnswer subjectsAnswer = userAnswers.get("3");
            if (subjectsAnswer != null && subjectsAnswer.getAnswer() != null) {
                List<String> subjects = new ArrayList<>();
                if (subjectsAnswer.getAnswer() instanceof List) {
                    @SuppressWarnings("unchecked")
                    List<String> subjectList = (List<String>) subjectsAnswer.getAnswer();
                    subjects.addAll(subjectList);
                }
                profile.setSubjects(subjects);
            }

            // 5. 提取总分
            StructuredUserDataReqVO.QuestionAnswer totalScoreAnswer = userAnswers.get("5");
            if (totalScoreAnswer != null && totalScoreAnswer.getAnswer() != null) {
                try {
                    profile.setTotalScore(Integer.parseInt(totalScoreAnswer.getAnswer().toString()));
                } catch (NumberFormatException e) {
                    log.warn("解析总分失败: {}", totalScoreAnswer.getAnswer());
                }
            }

            // 6. 提取各科分数
            StructuredUserDataReqVO.QuestionAnswer subjectScoresAnswer = userAnswers.get("6");
            if (subjectScoresAnswer != null && subjectScoresAnswer.getAnswer() != null) {
                Map<String, Integer> subjectScores = parseSubjectScores(subjectScoresAnswer.getAnswer().toString());
                profile.setSubjectScores(subjectScores);
            }

            // 7. 提取意向专业
            StructuredUserDataReqVO.QuestionAnswer interestedMajorsAnswer = userAnswers.get("7");
            if (interestedMajorsAnswer != null && interestedMajorsAnswer.getAnswer() != null) {
                List<String> interestedMajors = new ArrayList<>();
                if (interestedMajorsAnswer.getAnswer() instanceof List) {
                    @SuppressWarnings("unchecked")
                    List<String> majorList = (List<String>) interestedMajorsAnswer.getAnswer();
                    interestedMajors.addAll(majorList);
                }
                profile.setInterestedMajorCategories(interestedMajors);
            }

            // 8-10. 提取性格特点
            List<String> personalityTraits = new ArrayList<>();

            StructuredUserDataReqVO.QuestionAnswer personalityAnswer = userAnswers.get("8");
            if (personalityAnswer != null && personalityAnswer.getAnswer() != null) {
                personalityTraits.add(personalityAnswer.getAnswer().toString());
            }

            StructuredUserDataReqVO.QuestionAnswer learningAbilityAnswer = userAnswers.get("9");
            if (learningAbilityAnswer != null && learningAbilityAnswer.getAnswer() != null) {
                personalityTraits.add("学习能力" + learningAbilityAnswer.getAnswer().toString());
            }

            StructuredUserDataReqVO.QuestionAnswer socialAbilityAnswer = userAnswers.get("10");
            if (socialAbilityAnswer != null && socialAbilityAnswer.getAnswer() != null) {
                personalityTraits.add("社交能力" + socialAbilityAnswer.getAnswer().toString());
            }

            profile.setPersonalityTraits(personalityTraits);

            // 11. 提取家庭年收入
            StructuredUserDataReqVO.QuestionAnswer incomeAnswer = userAnswers.get("11");
            if (incomeAnswer != null && incomeAnswer.getAnswer() != null) {
                profile.setFamilyIncome(incomeAnswer.getAnswer().toString());
            }

            // 12. 提取就业方向
            StructuredUserDataReqVO.QuestionAnswer careerAnswer = userAnswers.get("12");
            if (careerAnswer != null && careerAnswer.getAnswer() != null) {
                profile.setCareerDirection(careerAnswer.getAnswer().toString());
            }

            // 14. 提取毕业去向
            StructuredUserDataReqVO.QuestionAnswer graduationAnswer = userAnswers.get("14");
            if (graduationAnswer != null && graduationAnswer.getAnswer() != null) {
                profile.setGraduationPlan(graduationAnswer.getAnswer().toString());
            }

            // 15. 提取就读城市省份
            StructuredUserDataReqVO.QuestionAnswer locationAnswer = userAnswers.get("15");
            if (locationAnswer != null && locationAnswer.getAnswer() != null) {
                profile.setPreferredLocation(locationAnswer.getAnswer().toString());
            }

            // 设置年份为2024（默认值）
            profile.setYear(2024);

            // 根据选科确定用户类型
            if (profile.getSubjects() != null && !profile.getSubjects().isEmpty()) {
                boolean hasPhysics = profile.getSubjects().stream().anyMatch(s -> s.contains("物理"));
                boolean hasHistory = profile.getSubjects().stream().anyMatch(s -> s.contains("历史"));

                String firstSubject = null;
                if (hasPhysics) {
                    firstSubject = "物理";
                } else if (hasHistory) {
                    firstSubject = "历史";
                }

                if (firstSubject != null) {
                    String typeName = determineSubjectSelection(profile.getProvince(), firstSubject);
                    profile.setTypeName(typeName);
                    log.info("根据用户选科确定类型为: {}", typeName);
                }
            }

            // 从结构化数据中获取最低分和最高分
            try {
                Integer userTotalScore = profile.getTotalScore();

                // 提取最低分
                StructuredUserDataReqVO.QuestionAnswer minScoreAnswer = userAnswers.get("minScore");
                if (minScoreAnswer != null && minScoreAnswer.getAnswer() != null) {
                    try {
                        int minScore = Integer.parseInt(minScoreAnswer.getAnswer().toString());

                        // 应用最低分规则：当最低分比用户分数低少于44分时，按44分算
                        if (userTotalScore != null) {
                            int scoreDiff = userTotalScore - minScore;
                            if (scoreDiff < 44) {
                                int adjustedMinScore = userTotalScore - 44;
                                log.info("最低分数调整: 原值{}, 用户分数{}, 差值{}分 < 44分, 调整为{}",
                                        minScore, userTotalScore, scoreDiff, adjustedMinScore);
                                minScore = adjustedMinScore;
                            }
                        }

                        profile.setMinScore(minScore);
                        log.info("从结构化数据中获取到最低分数: {}", minScore);
                    } catch (NumberFormatException e) {
                        log.warn("解析最低分数失败: {}", minScoreAnswer.getAnswer());
                    }
                }

                // 提取最高分
                StructuredUserDataReqVO.QuestionAnswer maxScoreAnswer = userAnswers.get("maxScore");
                if (maxScoreAnswer != null && maxScoreAnswer.getAnswer() != null) {
                    try {
                        int maxScore = Integer.parseInt(maxScoreAnswer.getAnswer().toString());

                        // 应用最高分规则：当最高分比用户分数高出的低于14分时，按14分算
                        if (userTotalScore != null) {
                            int scoreDiff = maxScore - userTotalScore;
                            if (scoreDiff < 14) {
                                int adjustedMaxScore = userTotalScore + 14;
                                log.info("最高分数调整: 原值{}, 用户分数{}, 差值{}分 < 14分, 调整为{}",
                                        maxScore, userTotalScore, scoreDiff, adjustedMaxScore);
                                maxScore = adjustedMaxScore;
                            }
                        }

                        profile.setMaxScore(maxScore);
                        log.info("从结构化数据中获取到最高分数: {}", maxScore);
                    } catch (NumberFormatException e) {
                        log.warn("解析最高分数失败: {}", maxScoreAnswer.getAnswer());
                    }
                }

                // 如果没有提供分数范围，记录日志
                if (profile.getMinScore() == null && profile.getMaxScore() == null) {
                    log.info("结构化数据中未找到分数范围信息，将使用默认分数范围计算");
                }
            } catch (Exception e) {
                log.warn("从结构化数据获取分数范围失败: {}", e.getMessage());
            }

        } catch (Exception e) {
            log.error("解析结构化用户数据失败", e);
        }

        return profile;
    }

    /**
     * 解析各科分数字符串
     * @param scoresStr 分数字符串，格式如："语文:88,数学:99,英语:88,历史:99,生物:99,政治:65"
     * @return 各科分数Map
     */
    private Map<String, Integer> parseSubjectScores(String scoresStr) {
        Map<String, Integer> subjectScores = new HashMap<>();
        if (StringUtils.hasText(scoresStr)) {
            String[] scoreItems = scoresStr.split(",");
            for (String item : scoreItems) {
                String[] parts = item.split(":");
                if (parts.length == 2) {
                    try {
                        String subject = parts[0].trim();
                        Integer score = Integer.parseInt(parts[1].trim());
                        subjectScores.put(subject, score);
                    } catch (NumberFormatException e) {
                        log.warn("解析科目分数失败: {}", item);
                    }
                }
            }
        }
        return subjectScores;
    }

    /**
     * 根据省份和首选科目确定科目选择类型
     *
     * @param province     省份
     * @param secondSubjcet 首选科目
     * @return 科目选择类型
     */
    private String determineSubjectSelection(String province, String secondSubjcet) {
        // 获取当前年份
        String year = String.valueOf(java.time.Year.now().getValue());

        // 使用SubjectSelectionUtils工具类获取科目选择类型
        return SubjectSelectionUtils.getSubjectSelectionType(province, year, secondSubjcet);
    }

    /**
     * 根据用户信息和指定年份确定对应的科目类型名称
     * 不同年份可能使用不同的科目类型名称（如2024年用"物理类"，2022年用"理科"）
     *
     * @param profile 用户信息
     * @param year 查询年份
     * @return 对应年份的科目类型名称
     */
    private String determineTypeNameForYear(UserProfileInfo profile, Integer year) {
        if (profile == null || year == null) {
            return null;
        }

        // 获取用户的首选科目
        String firstSubject = null;
        if (profile.getSubjects() != null && !profile.getSubjects().isEmpty()) {
            // 检查是否包含物理和历史，这两个是首选科目
            boolean hasPhysics = profile.getSubjects().stream().anyMatch(s -> s.contains("物理"));
            boolean hasHistory = profile.getSubjects().stream().anyMatch(s -> s.contains("历史"));

            if (hasPhysics) {
                firstSubject = "物理";
            } else if (hasHistory) {
                firstSubject = "历史";
            }
        }

        // 如果没有找到首选科目，使用当前profile中的typeName作为fallback
        if (firstSubject == null) {
            log.debug("未找到用户首选科目，使用当前profile的typeName: {}", profile.getTypeName());
            return profile.getTypeName();
        }

        // 使用SubjectSelectionUtils工具类根据省份、年份和首选科目获取对应的科目类型
        String typeNameForYear = SubjectSelectionUtils.getSubjectSelectionType(
                profile.getProvince(),
                String.valueOf(year),
                firstSubject
        );

        log.debug("根据省份: {}, 年份: {}, 首选科目: {} 确定科目类型为: {}",
                profile.getProvince(), year, firstSubject, typeNameForYear);

        return typeNameForYear;
    }

    /**
     * 根据用户个人信息推荐专业（优化版本）
     * 数据处理步骤：
     * 1. 先从专业录取分数线中获取对应的数据
     * 2. 再过滤招生计划
     * 3. 再分组
     * 4. 查询近三年录取分数和招生计划数据
     * @param profile 用户个人信息
     * @return 推荐的专业列表和推荐理由
     */
    public Map<String, Object> recommendMajors(UserProfileInfo profile) {
        long startTime = System.currentTimeMillis();
        log.info("开始专业推荐，用户省份：{}，分数：{}，选科：{}",
                profile.getProvince(), profile.getTotalScore(), profile.getSubjects());

        Map<String, Object> result = new HashMap<>();
        List<MajorAdmissionInfo> higherScoreMajors = new ArrayList<>();
        List<MajorAdmissionInfo> equalScoreMajors = new ArrayList<>();
        List<MajorAdmissionInfo> lowerScoreMajors = new ArrayList<>();
        StringBuilder recommendationReason = new StringBuilder();
        int totalCount = 0;

        // 构建推荐理由开头
        buildRecommendationReasonHeader(profile, recommendationReason);

        try {
            // 第一步：从专业录取分数线中获取对应的数据（与getAllSuitableMajors保持一致）
            List<MajorAdmissionInfo> admissionInfos = queryMajorAdmissionDataByConditions(profile);
            log.info("第一步：从专业录取分数线中获取得到 {} 条数据", admissionInfos.size());

            if (admissionInfos.isEmpty()) {
                return buildEmptyResult(profile, recommendationReason);
            }

            // 第二步：过滤招生计划（与getAllSuitableMajors保持一致）
            List<MajorAdmissionInfo> filteredMajors = batchFilterEnrollmentPlansOptimized(admissionInfos, profile);
            log.info("第二步：过滤招生计划后剩余 {} 条数据", filteredMajors.size());

            if (filteredMajors.isEmpty()) {
                return buildEmptyResult(profile, recommendationReason);
            }

            // 第三步：按冲稳保分组（与getAllSuitableMajors保持一致）
            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByScore(filteredMajors, profile.getTotalScore());

            higherScoreMajors = classifiedMajors.get("rush");
            equalScoreMajors = classifiedMajors.get("stable");
            lowerScoreMajors = classifiedMajors.get("safe");

            log.info("第三步：专业分组完成 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                    higherScoreMajors.size(), equalScoreMajors.size(), lowerScoreMajors.size());

            // 第四步：按冲稳保分组后，某个等级内的专业超过了10条则截取与用户分数最接近的10条
            higherScoreMajors = limitMajorsByClosestScore(higherScoreMajors, profile.getTotalScore(), "冲刺");
            equalScoreMajors = limitMajorsByClosestScore(equalScoreMajors, profile.getTotalScore(), "稳妥");
            lowerScoreMajors = limitMajorsByClosestScore(lowerScoreMajors, profile.getTotalScore(), "保底");

            log.info("第四步：专业数量限制完成 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                    higherScoreMajors.size(), equalScoreMajors.size(), lowerScoreMajors.size());

            // 构建推荐理由
            buildRecommendationReasonContent(profile, filteredMajors, recommendationReason);

            // 第五步：查询近三年专业录取分数数据和招生计划数据（与getAllSuitableMajors保持一致）
            log.info("第五步：开始查询近三年录取分数和招生计划数据，专业总数：{}",
                    higherScoreMajors.size() + equalScoreMajors.size() + lowerScoreMajors.size());

            if (!higherScoreMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(higherScoreMajors, profile);
                batchQueryThreeYearsEnrollmentPlans(higherScoreMajors, profile);
                log.info("为冲刺等级查询近三年数据完成");
            }
            if (!equalScoreMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(equalScoreMajors, profile);
                batchQueryThreeYearsEnrollmentPlans(equalScoreMajors, profile);
                log.info("为稳妥等级查询近三年数据完成");
            }
            if (!lowerScoreMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(lowerScoreMajors, profile);
                batchQueryThreeYearsEnrollmentPlans(lowerScoreMajors, profile);
                log.info("为保底等级查询近三年数据完成");
            }
            log.info("第五步：查询近三年专业录取分数和招生计划数据完成");

            // 更新总数
            totalCount = higherScoreMajors.size() + equalScoreMajors.size() + lowerScoreMajors.size();

        } catch (Exception e) {
            log.error("专业推荐过程中发生异常", e);
            return buildErrorResult(e.getMessage());
        }

        // 构建最终结果
        result.put("higherScoreMajors", higherScoreMajors);
        result.put("equalScoreMajors", equalScoreMajors);
        result.put("lowerScoreMajors", lowerScoreMajors);
        result.put("totalCount", totalCount);
        result.put("recommendationReason", recommendationReason.toString());

        // 添加分类说明
        if (totalCount > 0) {
            addCategoryExplanation(recommendationReason, higherScoreMajors, equalScoreMajors, lowerScoreMajors);
        }

        long endTime = System.currentTimeMillis();
        log.info("专业推荐完成，耗时：{}ms，推荐专业总数：{}", endTime - startTime, totalCount);

        return result;
    }

    /**
     * 构建推荐理由开头
     */
    private void buildRecommendationReasonHeader(UserProfileInfo profile, StringBuilder recommendationReason) {
        recommendationReason.append("根据您的个人情况，我们为您推荐以下专业：\n\n");
        recommendationReason.append("1. 您来自").append(profile.getProvince()).append("，");
        recommendationReason.append(profile.getYear()).append("年高考，");
        recommendationReason.append("选科为").append(String.join("、", profile.getSubjects())).append("，");
        recommendationReason.append("高考总分为").append(profile.getTotalScore()).append("分。\n");

        recommendationReason.append("2. 您的性格特点为").append(String.join("、", profile.getPersonalityTraits())).append("，");
        if ("就业".equals(profile.getGraduationPlan())) {
            recommendationReason.append("毕业后计划直接就业。\n");
        } else {
            recommendationReason.append("毕业后的计划是").append(profile.getGraduationPlan()).append("。\n");
        }

        recommendationReason.append("3. 您对").append(String.join("、", profile.getInterestedMajorCategories())).append("等专业类别感兴趣。\n\n");
    }







    /**
     * 构建推荐理由内容
     */
    private void buildRecommendationReasonContent(UserProfileInfo profile, List<MajorAdmissionInfo> majorsWithEnrollmentPlan, StringBuilder recommendationReason) {
        recommendationReason.append("\n我们为您找到了").append(majorsWithEnrollmentPlan.size()).append("个符合您条件的院校和专业。");
        recommendationReason.append("这些专业的录取分数线与您的分数相匹配，并且符合您的选科要求。\n");

        // 列出前5个院校和专业
        int count = Math.min(5, majorsWithEnrollmentPlan.size());
        for (int i = 0; i < count; i++) {
            MajorAdmissionInfo info = majorsWithEnrollmentPlan.get(i);
            recommendationReason.append("- ").append(info.getSchoolName()).append(" ");
            recommendationReason.append(info.getMajorName()).append("，");
            recommendationReason.append("录取分数线：").append(info.getLowestScore()).append("\n");
        }

        recommendationReason.append("\n总结：以上推荐的专业符合您的兴趣方向，并且考虑了您的分数和选科情况。");
        recommendationReason.append("这些专业在就业市场有较好的前景，适合您的性格特点和职业规划。");
        recommendationReason.append("建议您进一步了解这些院校和专业的详细信息，以做出更好的选择。");
    }

    /**
     * 构建空结果
     */
    private Map<String, Object> buildEmptyResult(UserProfileInfo profile, StringBuilder recommendationReason) {
        Map<String, Object> result = new HashMap<>();

        recommendationReason.append("\n根据您的兴趣专业类别，我们没有找到完全匹配的专业。");
        recommendationReason.append("\n建议您尝试以下方法：");
        recommendationReason.append("\n1. 提供更多感兴趣的专业类别");
        recommendationReason.append("\n2. 调整您的分数范围");
        recommendationReason.append("\n3. 考虑其他省份的院校");
        recommendationReason.append("\n4. 联系我们的客服获取更多帮助");

        result.put("higherScoreMajors", new ArrayList<>());
        result.put("equalScoreMajors", new ArrayList<>());
        result.put("lowerScoreMajors", new ArrayList<>());
        result.put("totalCount", 0);
        result.put("recommendationReason", recommendationReason.toString());
        return result;
    }

    /**
     * 构建错误结果
     */
    private Map<String, Object> buildErrorResult(String errorMessage) {
        Map<String, Object> result = new HashMap<>();
        result.put("higherScoreMajors", new ArrayList<>());
        result.put("equalScoreMajors", new ArrayList<>());
        result.put("lowerScoreMajors", new ArrayList<>());
        result.put("totalCount", 0);
        result.put("recommendationReason", "推荐过程中发生错误：" + errorMessage);
        return result;
    }





    /**
     * 添加分类说明
     */
    private void addCategoryExplanation(StringBuilder recommendationReason,
                                       List<MajorAdmissionInfo> higherScoreMajors,
                                       List<MajorAdmissionInfo> equalScoreMajors,
                                       List<MajorAdmissionInfo> lowerScoreMajors) {
        recommendationReason.append("\n\n我们将推荐的专业分为三类（每类仅显示分数最接近的专业）：\n");
        recommendationReason.append("1. 分数比您高的专业：").append(higherScoreMajors.size()).append("个\n");
        recommendationReason.append("2. 分数与您相近的专业：").append(equalScoreMajors.size()).append("个\n");
        recommendationReason.append("3. 分数比您低的专业：").append(lowerScoreMajors.size()).append("个\n");
        recommendationReason.append("您可以根据自己的实际情况和偏好选择适合的专业。");
    }





    /**
     * 去除专业名称中的括号及其内容（支持多重括号）
     * 支持中文括号（）和英文括号()
     * 例如：日语（师范类，地方专项计划）（地方专项计划） -> 日语
     * @param majorName 专业名称
     * @return 清理后的专业名称
     */
    private String removeBrackets(String majorName) {
        if (!StringUtils.hasText(majorName)) {
            return majorName;
        }

        String result = majorName;
        // 循环移除所有括号，直到没有括号为止
        // 同时支持中文括号（）和英文括号()
        while (result.matches(".*[\\(（][^\\)）]*[\\)）].*")) {
            result = result.replaceAll("[\\(（][^\\)）]*[\\)）]", "").trim();
        }

        return result;
    }

    /**
     * 提取专业名称中括号内的所有专业名称（支持多重括号）
     * 支持中文括号（）和英文括号()
     * 例如：计算机类(计算机科学与技术、软件工程) -> [计算机科学与技术, 软件工程]
     * 例如：日语（师范类，地方专项计划）（地方专项计划） -> [师范类, 地方专项计划, 地方专项计划]
     * @param majorName 包含括号的专业名称
     * @return 括号内的专业名称列表
     */
    private List<String> extractMajorNamesFromBrackets(String majorName) {
        List<String> result = new ArrayList<>();

        if (!StringUtils.hasText(majorName)) {
            return result;
        }

        // 使用正则表达式匹配所有括号内容（支持中文和英文括号）
        Pattern pattern = Pattern.compile("[\\(（]([^\\)）]*)[\\)）]");
        Matcher matcher = pattern.matcher(majorName);

        while (matcher.find()) {
            String bracketContent = matcher.group(1);
            if (StringUtils.hasText(bracketContent)) {
                // 按照中文顿号、逗号等分隔符分割
                String[] parts = bracketContent.split("[、，,]");

                for (String part : parts) {
                    String trimmed = part.trim();
                    if (!trimmed.isEmpty()) {
                        result.add(trimmed);
                    }
                }
            }
        }

        return result;
    }

    /**
     * 检查两个专业名称是否匹配（支持括号内容匹配）
     * @param majorName1 专业名称1
     * @param majorName2 专业名称2
     * @return 是否匹配
     */
    private boolean isMajorNameMatch(String majorName1, String majorName2) {
        if (!StringUtils.hasText(majorName1) || !StringUtils.hasText(majorName2)) {
            return false;
        }

        // 1. 直接匹配
        if (majorName1.equals(majorName2)) {
            return true;
        }

        // 2. 去除括号后匹配
        String clean1 = removeBrackets(majorName1);
        String clean2 = removeBrackets(majorName2);
        if (clean1.equals(clean2)) {
            return true;
        }

        // 3. 检查是否有一个专业名称在另一个的括号内
        List<String> brackets1 = extractMajorNamesFromBrackets(majorName1);
        List<String> brackets2 = extractMajorNamesFromBrackets(majorName2);

        // 检查 majorName2 的去括号名称是否在 majorName1 的括号内
        if (brackets1.contains(clean2)) {
            return true;
        }

        // 检查 majorName1 的去括号名称是否在 majorName2 的括号内
        if (brackets2.contains(clean1)) {
            return true;
        }

        // 4. 检查括号内的专业名称是否有交集
        for (String bracket1 : brackets1) {
            if (brackets2.contains(bracket1)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 将专业名称拆分为关键词
     *
     * @param majorName 专业名称
     * @return 关键词列表
     */
    private List<String> splitMajorNameToKeywords(String majorName) {
        if (!StringUtils.hasText(majorName)) {
            return new ArrayList<>();
        }

        // 去除专业名称中的括号及其内容
        String cleanMajorName = removeBrackets(majorName);

        // 使用中文分词工具类进行分词
        return ChineseSegmentationUtil.segment(cleanMajorName);
    }

    /**
     * 将用户选科列表转换为API所需的选科要求格式
     * @param subjects 用户选科列表
     * @return 符合API要求的选科格式
     */
    private String convertToSubjectSelectionFormat(List<String> subjects) {
        if (subjects == null || subjects.isEmpty()) {
            return "";
        }

        // 检查是否包含物理和历史，这两个是首选科目
        boolean hasPhysics = subjects.stream().anyMatch(s -> s.contains("物理"));
        boolean hasHistory = subjects.stream().anyMatch(s -> s.contains("历史"));

        // 如果既有物理又有历史，返回空字符串
        if (hasPhysics && hasHistory) {
            return "";
        }

        // 检查是否包含化学、生物、地理、政治（思想政治）
        boolean hasChemistry = subjects.stream().anyMatch(s -> s.contains("化学"));
        boolean hasBiology = subjects.stream().anyMatch(s -> s.contains("生物"));
        boolean hasGeography = subjects.stream().anyMatch(s -> s.contains("地理"));
        boolean hasPolitics = subjects.stream().anyMatch(s -> s.contains("政治") || s.contains("思想政治"));

        StringBuilder result = new StringBuilder();

        // 构建选科要求格式
        if (hasPhysics) {
            result.append("首选物理，再选");

            // 添加再选科目
            if (hasChemistry && !hasBiology && !hasGeography && !hasPolitics) {
                result.append("化学");
            } else if (!hasChemistry && hasBiology && !hasGeography && !hasPolitics) {
                result.append("生物");
            } else if (!hasChemistry && !hasBiology && hasGeography && !hasPolitics) {
                result.append("地理");
            } else if (!hasChemistry && !hasBiology && !hasGeography && hasPolitics) {
                result.append("思想政治");
            } else if (hasChemistry && hasBiology && !hasGeography && !hasPolitics) {
                result.append("化学/生物(2选1)");
            } else if (hasChemistry && !hasBiology && hasGeography && !hasPolitics) {
                result.append("化学/地理(2选1)");
            } else if (hasChemistry && !hasBiology && !hasGeography && hasPolitics) {
                result.append("化学/思想政治(2选1)");
            } else if (!hasChemistry && hasBiology && hasGeography && !hasPolitics) {
                result.append("生物/地理(2选1)");
            } else if (!hasChemistry && hasBiology && !hasGeography && hasPolitics) {
                result.append("生物/思想政治(2选1)");
            } else if (!hasChemistry && !hasBiology && hasGeography && hasPolitics) {
                result.append("地理/思想政治(2选1)");
            } else {
                result.append("");
            }
        } else if (hasHistory) {
            result.append("首选历史，再选");

            // 添加再选科目
            if (hasChemistry && !hasBiology && !hasGeography && !hasPolitics) {
                result.append("化学");
            } else if (!hasChemistry && hasBiology && !hasGeography && !hasPolitics) {
                result.append("生物");
            } else if (!hasChemistry && !hasBiology && hasGeography && !hasPolitics) {
                result.append("地理");
            } else if (!hasChemistry && !hasBiology && !hasGeography && hasPolitics) {
                result.append("思想政治");
            } else if (hasChemistry && hasBiology && !hasGeography && !hasPolitics) {
                result.append("化学/生物(2选1)");
            } else if (hasChemistry && !hasBiology && hasGeography && !hasPolitics) {
                result.append("化学/地理(2选1)");
            } else if (hasChemistry && !hasBiology && !hasGeography && hasPolitics) {
                result.append("化学/思想政治(2选1)");
            } else if (!hasChemistry && hasBiology && hasGeography && !hasPolitics) {
                result.append("生物/地理(2选1)");
            } else if (!hasChemistry && hasBiology && !hasGeography && hasPolitics) {
                result.append("生物/思想政治(2选1)");
            } else if (!hasChemistry && !hasBiology && hasGeography && hasPolitics) {
                result.append("地理/思想政治(2选1)");
            } else {
                result.append("");
            }
        } else {
            // 如果没有物理和历史，返回空字符串
            return "";
        }

        return result.toString();
    }

    /**
     * 检查用户选科是否符合专业的选科要求
     * @param userSubjects 用户选科集合
     * @param courseSelectionRequirements 专业选科要求字符串
     * @return 是否符合要求
     */
    private boolean checkSubjectRequirements(Set<String> userSubjects, String courseSelectionRequirements) {
        if (courseSelectionRequirements == null || courseSelectionRequirements.trim().isEmpty()) {
            return true; // 没有选科要求，默认符合
        }

        String requirements = courseSelectionRequirements.trim();

        // 不限选科
        if ("不限".equals(requirements)) {
            return true;
        }

        // 如果用户没有选科信息，但专业有选科要求，则不符合
        if (userSubjects == null || userSubjects.isEmpty()) {
            log.debug("用户未提供选科信息，但专业有选科要求: {}", requirements);
            return false;
        }

        // 标准化用户选科名称
        Set<String> normalizedUserSubjects = normalizeSubjectNames(userSubjects);

        // 如果标准化后的选科为空，也不符合要求
        if (normalizedUserSubjects.isEmpty()) {
            log.debug("用户选科标准化后为空，但专业有选科要求: {}", requirements);
            return false;
        }

        log.debug("检查选科要求: {} vs 用户选科: {}", requirements, normalizedUserSubjects);

        // 处理各种选科要求格式（注意：更具体的条件要先判断）
        if (requirements.contains("科必选")) {
            return checkMultipleMustSelectRequirements(normalizedUserSubjects, requirements);
        } else if (requirements.contains("选1") || requirements.contains("2选1")) {
            return checkSelectOneRequirements(normalizedUserSubjects, requirements);
        } else if (requirements.contains("必选")) {
            return checkMustSelectRequirements(normalizedUserSubjects, requirements);
        } else if (requirements.contains("首选") && requirements.contains("再选")) {
            // 处理首选+再选格式，如："首选物理，再选不限"、"首选历史，再选化学"
            return checkComplexSubjectRequirements(normalizedUserSubjects, requirements);
        } else {
            // 默认处理：解析为必选科目
            return checkDefaultRequirements(normalizedUserSubjects, requirements);
        }
    }

    /**
     * 标准化选科名称
     */
    private Set<String> normalizeSubjectNames(Set<String> subjects) {
        Set<String> normalized = new HashSet<>();
        for (String subject : subjects) {
            String normalizedSubject = normalizeSubjectName(subject);
            if (normalizedSubject != null) {
                normalized.add(normalizedSubject);
            }
        }
        return normalized;
    }

    /**
     * 标准化单个选科名称
     */
    private String normalizeSubjectName(String subject) {
        if (subject == null) {
            return null;
        }

        String cleaned = subject.trim();

        // 标准化映射
        if (cleaned.contains("物理")) {
            return "物理";
        }
        if (cleaned.contains("化学")) {
            return "化学";
        }
        if (cleaned.contains("生物")) {
            return "生物";
        }
        if (cleaned.contains("历史")) {
            return "历史";
        }
        if (cleaned.contains("地理")) {
            return "地理";
        }
        if (cleaned.contains("政治") || cleaned.contains("思想政治")) {
            return "政治";
        }

        return cleaned;
    }

    /**
     * 检查必选科目要求（如：物理必选、化学必选）
     */
    private boolean checkMustSelectRequirements(Set<String> userSubjects, String requirements) {
        if (requirements.contains("物理必选") && !userSubjects.contains("物理")) {
            return false;
        }
        if (requirements.contains("化学必选") && !userSubjects.contains("化学")) {
            return false;
        }
        if (requirements.contains("生物必选") && !userSubjects.contains("生物")) {
            return false;
        }
        if (requirements.contains("历史必选") && !userSubjects.contains("历史")) {
            return false;
        }
        if (requirements.contains("地理必选") && !userSubjects.contains("地理")) {
            return false;
        }
        if (requirements.contains("思想政治必选") && !userSubjects.contains("政治")) {
            return false;
        }
        return true;
    }

    /**
     * 检查选一科目要求（如：物理/化学(2选1)、物/化/生(3选1)）
     */
    private boolean checkSelectOneRequirements(Set<String> userSubjects, String requirements) {
        // 提取选科选项
        Set<String> options = new HashSet<>();

        if (requirements.contains("物理/化学(2选1)")) {
            options.add("物理");
            options.add("化学");
        } else if (requirements.contains("物/化/生(3选1)")) {
            options.add("物理");
            options.add("化学");
            options.add("生物");
        } else if (requirements.contains("物/化/地(3选1)")) {
            options.add("物理");
            options.add("化学");
            options.add("地理");
        } else if (requirements.contains("化学/生物(2选1)")) {
            options.add("化学");
            options.add("生物");
        } else if (requirements.contains("史/生/政(3选1)")) {
            options.add("历史");
            options.add("生物");
            options.add("政治");
        } else if (requirements.contains("物/史/地(3选1)")) {
            options.add("物理");
            options.add("历史");
            options.add("地理");
        } else if (requirements.contains("生/政/地(3选1)")) {
            options.add("生物");
            options.add("政治");
            options.add("地理");
        } else if (requirements.contains("历史/地理(2选1)")) {
            options.add("历史");
            options.add("地理");
        } else if (requirements.contains("物/生/地(3选1)")) {
            options.add("物理");
            options.add("生物");
            options.add("地理");
        } else if (requirements.contains("物理/历史(2选1)")) {
            options.add("物理");
            options.add("历史");
        } else if (requirements.contains("史/政/地(3选1)")) {
            options.add("历史");
            options.add("政治");
            options.add("地理");
        } else if (requirements.contains("物理/地理(2选1)")) {
            options.add("物理");
            options.add("地理");
        } else if (requirements.contains("物/政/地(3选1)")) {
            options.add("物理");
            options.add("政治");
            options.add("地理");
        } else if (requirements.contains("史/化/地(3选1)")) {
            options.add("历史");
            options.add("化学");
            options.add("地理");
        }

        // 检查用户是否选择了其中至少一科
        for (String option : options) {
            if (userSubjects.contains(option)) {
                return true;
            }
        }

        return options.isEmpty(); // 如果没有识别到选项，默认通过
    }

    /**
     * 检查多科必选要求（如：化学、生物(2科必选)、物理、化学(2科必选)）
     */
    private boolean checkMultipleMustSelectRequirements(Set<String> userSubjects, String requirements) {
        // 处理简单的多科必选格式
        if (requirements.contains("化学、生物(2科必选)")) {
            return userSubjects.contains("化学") && userSubjects.contains("生物");
        } else if (requirements.contains("物理、化学(2科必选)")) {
            return userSubjects.contains("物理") && userSubjects.contains("化学");
        } else if (requirements.contains("历史、地理(2科必选)")) {
            return userSubjects.contains("历史") && userSubjects.contains("地理");
        } else if (requirements.contains("物、化、生(3科必选)")) {
            return userSubjects.contains("物理") && userSubjects.contains("化学") && userSubjects.contains("生物");
        } else if (requirements.contains("史、政、地(3科必选)")) {
            return userSubjects.contains("历史") && userSubjects.contains("政治") && userSubjects.contains("地理");
        } else if (requirements.contains("物理、生物(2科必选)")) {
            return userSubjects.contains("物理") && userSubjects.contains("生物");
        }

        // 处理复杂的首选+再选格式，如："首选物理，再选化学、生物(2科必选)"
        if (requirements.contains("首选") && requirements.contains("再选") && requirements.contains("科必选")) {
            return checkComplexSubjectRequirements(userSubjects, requirements);
        }

        return true; // 未识别的格式默认通过
    }

    /**
     * 检查复杂的选科要求（如：首选物理，再选化学、生物(2科必选)）
     */
    private boolean checkComplexSubjectRequirements(Set<String> userSubjects, String requirements) {
        log.debug("检查复杂选科要求: {} vs 用户选科: {}", requirements, userSubjects);

        // 检查首选科目
        String firstSubject = null;
        if (requirements.contains("首选物理")) {
            firstSubject = "物理";
        } else if (requirements.contains("首选历史")) {
            firstSubject = "历史";
        }

        if (firstSubject != null && !userSubjects.contains(firstSubject)) {
            log.debug("用户未选择首选科目: {}", firstSubject);
            return false;
        }

        // 检查再选科目的必选要求
        if (requirements.contains("再选")) {
            // 提取再选部分
            int reSelectIndex = requirements.indexOf("再选");
            String reSelectPart = requirements.substring(reSelectIndex + 2).trim();

            // 处理"再选不限"的情况
            if ("不限".equals(reSelectPart) || reSelectPart.startsWith("不限")) {
                log.debug("再选要求为不限，直接通过检查");
                // 再选不限，直接通过
            } else if (reSelectPart.contains("化学、生物(2科必选)")) {
                boolean hasChemistry = userSubjects.contains("化学");
                boolean hasBiology = userSubjects.contains("生物");
                if (!hasChemistry || !hasBiology) {
                    log.debug("用户未同时选择化学和生物，用户选科: {}", userSubjects);
                    return false;
                }
            } else if (reSelectPart.contains("物理、化学(2科必选)")) {
                boolean hasPhysics = userSubjects.contains("物理");
                boolean hasChemistry = userSubjects.contains("化学");
                if (!hasPhysics || !hasChemistry) {
                    log.debug("用户未同时选择物理和化学，用户选科: {}", userSubjects);
                    return false;
                }
            } else if (reSelectPart.contains("历史、地理(2科必选)")) {
                boolean hasHistory = userSubjects.contains("历史");
                boolean hasGeography = userSubjects.contains("地理");
                if (!hasHistory || !hasGeography) {
                    log.debug("用户未同时选择历史和地理，用户选科: {}", userSubjects);
                    return false;
                }
            } else if (reSelectPart.contains("物理、生物(2科必选)")) {
                boolean hasPhysics = userSubjects.contains("物理");
                boolean hasBiology = userSubjects.contains("生物");
                if (!hasPhysics || !hasBiology) {
                    log.debug("用户未同时选择物理和生物，用户选科: {}", userSubjects);
                    return false;
                }
            } else if (reSelectPart.contains("化学、地理(2科必选)")) {
                boolean hasChemistry = userSubjects.contains("化学");
                boolean hasGeography = userSubjects.contains("地理");
                if (!hasChemistry || !hasGeography) {
                    log.debug("用户未同时选择化学和地理，用户选科: {}", userSubjects);
                    return false;
                }
            } else if (reSelectPart.contains("生物、地理(2科必选)")) {
                boolean hasBiology = userSubjects.contains("生物");
                boolean hasGeography = userSubjects.contains("地理");
                if (!hasBiology || !hasGeography) {
                    log.debug("用户未同时选择生物和地理，用户选科: {}", userSubjects);
                    return false;
                }
            } else if (reSelectPart.contains("政治、地理(2科必选)")) {
                boolean hasPolitics = userSubjects.contains("政治");
                boolean hasGeography = userSubjects.contains("地理");
                if (!hasPolitics || !hasGeography) {
                    log.debug("用户未同时选择政治和地理，用户选科: {}", userSubjects);
                    return false;
                }
            }
            // 可以继续添加更多的再选组合...
        }

        log.debug("复杂选科要求检查通过");
        return true;
    }

    /**
     * 检查默认选科要求
     */
    private boolean checkDefaultRequirements(Set<String> userSubjects, String requirements) {
        // 解析选科要求中的科目
        Set<String> requiredSubjects = parseSubjectSelection(requirements);

        // 检查用户是否选择了所有要求的科目
        for (String required : requiredSubjects) {
            String normalized = normalizeSubjectName(required);
            if (normalized != null && !userSubjects.contains(normalized)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 解析选科要求字符串，例如"首选物理，再选化学"
     *
     * @param subjectSelection 选科要求字符串
     * @return 选科要求集合
     */
    private Set<String> parseSubjectSelection(String subjectSelection) {
        Set<String> subjects = new HashSet<>();
        if (subjectSelection == null || subjectSelection.isEmpty()) {
            return subjects;
        }

        // 处理首选科目
        if (subjectSelection.contains("首选")) {
            int firstStart = subjectSelection.indexOf("首选") + 2; // "首选"长度为2
            int firstEnd = subjectSelection.indexOf("，", firstStart); // 逗号分隔首选和再选
            if (firstEnd == -1) {
                // 如果没有逗号，可能只有首选科目
                firstEnd = subjectSelection.length();
            }
            String firstSubject = subjectSelection.substring(firstStart, firstEnd).trim();
            subjects.add(firstSubject);
        }

        // 处理再选科目
        if (subjectSelection.contains("再选")) {
            int secondStart = subjectSelection.indexOf("再选") + 2; // "再选"长度为2
            String secondPart = subjectSelection.substring(secondStart).trim();

            // 处理"再选不限"的情况 - 不限不需要添加到必选科目中
            if ("不限".equals(secondPart) || secondPart.startsWith("不限")) {
                // 再选不限，不添加任何科目要求
                log.debug("解析到再选不限，不添加科目要求");
            } else if (secondPart.contains("/") && secondPart.contains("(2选1)")) {
                // 处理形如"化学/生物(2选1)"的格式
                String[] options = secondPart.split("/");
                if (options.length >= 2) {
                    String option1 = options[0].trim();
                    String option2 = options[1].split("\\(")[0].trim();
                    subjects.add(option1);
                    subjects.add(option2);
                }
            } else {
                // 如果是单一科目
                subjects.add(secondPart);
            }
        }

        return subjects;
    }

    /**
     * 将MajorAdmissionDO转换为MajorAdmissionInfo
     * @param admissionDO MajorAdmissionDO对象
     * @return MajorAdmissionInfo对象
     */
    private MajorAdmissionInfo convertToMajorAdmissionInfo(MajorAdmissionDO admissionDO) {
        if (admissionDO == null) {
            return null;
        }

        MajorAdmissionInfo info = new MajorAdmissionInfo();
        info.setProvinceName(admissionDO.getProvinceName());
        info.setSchoolUUID(admissionDO.getSchoolUuid());
        info.setSchoolName(admissionDO.getSchoolName());
        info.setMajorName(admissionDO.getMajorName());
        info.setMajorCode(admissionDO.getMajorCode());
        info.setYear(admissionDO.getYear());
        info.setHighScore(admissionDO.getHighScore());
        info.setAverageScore(admissionDO.getAverageScore());
        info.setLowestScore(admissionDO.getLowestScore());
        info.setLowestSection(admissionDO.getLowestSection());
        info.setBatchName(admissionDO.getBatchName());
        info.setTypeName(admissionDO.getTypeName());
        info.setProScore(admissionDO.getProScore());
        info.setSubjectSelection(admissionDO.getSubjectSelection());
        info.setSubjectGroup(admissionDO.getSubjectGroup());
        info.setMajorStandardCode(admissionDO.getMajorStandardCode());
        return info;
    }

    /**
     * 将MajorAdmissionDO列表转换为MajorAdmissionInfo列表
     * @param admissionDOList MajorAdmissionDO列表
     * @return MajorAdmissionInfo列表
     */
    private List<MajorAdmissionInfo> convertToMajorAdmissionInfoList(List<MajorAdmissionDO> admissionDOList) {
        if (admissionDOList == null || admissionDOList.isEmpty()) {
            return new ArrayList<>();
        }

        List<MajorAdmissionInfo> result = new ArrayList<>(admissionDOList.size());
        for (MajorAdmissionDO admissionDO : admissionDOList) {
            MajorAdmissionInfo info = convertToMajorAdmissionInfo(admissionDO);
            if (info != null) {
                result.add(info);
            }
        }
        return result;
    }

    /**
     * 将MajorAdmissionDO转换为MajorAdmissionInfo.HistoricalYearData
     * @param admissionDO MajorAdmissionDO
     * @return HistoricalYearData
     */
    private MajorAdmissionInfo.HistoricalYearData convertToHistoricalYearData(MajorAdmissionDO admissionDO) {
        if (admissionDO == null) {
            return null;
        }

        MajorAdmissionInfo.HistoricalYearData yearData = new MajorAdmissionInfo.HistoricalYearData();
        yearData.setYear(admissionDO.getYear());
        yearData.setHighScore(admissionDO.getHighScore());
        yearData.setAverageScore(admissionDO.getAverageScore());
        yearData.setLowestScore(admissionDO.getLowestScore());
        yearData.setLowestSection(admissionDO.getLowestSection());
        return yearData;
    }

    /**
     * 将CollegeEnrollmentPlanDO转换为CollegeEnrollmentPlanInfo
     * @param planDO CollegeEnrollmentPlanDO
     * @return CollegeEnrollmentPlanInfo
     */
    private CollegeEnrollmentPlanInfo convertToCollegeEnrollmentPlanInfo(CollegeEnrollmentPlanDO planDO) {
        if (planDO == null) {
            return null;
        }

        CollegeEnrollmentPlanInfo planInfo = new CollegeEnrollmentPlanInfo();

        // 基本信息字段
        planInfo.setProvinceName(planDO.getProvinceName());
        planInfo.setSchoolUuid(planDO.getSchoolUuid());
        planInfo.setSchoolName(planDO.getSchoolName());
        planInfo.setCollegeMajorName(planDO.getCollegeMajorName());
        planInfo.setCollegeMajorCode(planDO.getCollegeMajorCode());
        planInfo.setYear(planDO.getYear());

        // 招生相关字段
        planInfo.setEnrollmentNumbers(planDO.getEnrollmentNumbers());
        planInfo.setInSchoolYears(planDO.getInSchoolYears());
        planInfo.setBatchName(planDO.getBatchName());
        planInfo.setType(planDO.getType());

        // 专业分类字段
        planInfo.setClassOne(planDO.getClassOne());
        planInfo.setClassTwo(planDO.getClassTwo());

        // 选科要求
        planInfo.setCourseSelectionRequirements(planDO.getCourseSelectionRequirements());

        // 专业组相关字段
        planInfo.setSpecialGroup(planDO.getSpecialGroup());
        planInfo.setSpecialCode(planDO.getSpecialCode());
        planInfo.setSpecialGroupName(planDO.getSpecialGroupName());

        log.debug("转换招生计划数据: 学校={}, 专业={}, 年份={}, 招生人数={}, 专业组={}, 专业组名称={}",
                planDO.getSchoolName(), planDO.getCollegeMajorName(), planDO.getYear(), planDO.getEnrollmentNumbers(),
                planDO.getSpecialGroup(), planDO.getSpecialGroupName());

        return planInfo;
    }



    /**
     * 为单个专业查询招生计划数据（带缓存）
     * @param admissionInfo 专业信息
     * @param profile 用户个人信息
     * @return 招生计划数据列表，如果没有数据则返回null或空列表
     */
    private List<CollegeEnrollmentPlanInfo> queryEnrollmentPlanForMajor(MajorAdmissionInfo admissionInfo, UserProfileInfo profile) {
        try {
            // 设置招生计划数据加载状态
            admissionInfo.setEnrollmentPlanDataLoading(true);

            log.debug("正在查询招生计划数据: {} - {}", admissionInfo.getMajorName(), admissionInfo.getSchoolName());

            // 使用缓存服务查询招生计划数据
            List<CollegeEnrollmentPlanInfo> enrollmentPlanList = collegeEnrollmentPlanService.getEnrollmentPlanForMajor(
                    admissionInfo.getSchoolName(),
                    admissionInfo.getMajorName(),
                    profile.getProvince(),
                    profile.getTypeName(),
                    2024 // 查询2024年的招生计划数据
                    );

            if (enrollmentPlanList != null && !enrollmentPlanList.isEmpty()) {
                log.debug("成功获取招生计划数据: {} - {}, 数据量: {}",
                        admissionInfo.getMajorName(), admissionInfo.getSchoolName(), enrollmentPlanList.size());
                return enrollmentPlanList;
            } else {
                log.debug("未找到招生计划数据: {} - {}", admissionInfo.getMajorName(), admissionInfo.getSchoolName());
                return null;
            }

        } catch (Exception e) {
            log.error("查询招生计划数据异常: {} - {}, 错误: {}",
                    admissionInfo.getMajorName(), admissionInfo.getSchoolName(), e.getMessage(), e);
            return null;
        } finally {
            // 无论成功失败，都设置加载状态为false
            admissionInfo.setEnrollmentPlanDataLoading(false);
        }
    }

    /**
     * 根据用户个人信息获取所有适合的专业（兼容性方法，默认返回所有等级）
     * @param profile 用户个人信息
     * @return 所有适合的专业列表
     */
    public Map<String, Object> getAllSuitableMajors(UserProfileInfo profile) {
        return getAllSuitableMajors(profile, Arrays.asList("rush", "stable", "safe"));
    }

    /**
     * 根据用户个人信息获取所有适合的专业（优化版本）
     * 数据处理步骤：
     * 1. 先从专业录取分数线中获取对应的数据
     * 2. 再过滤招生计划
     * 3. 再分组
     * 4. 按需查询近三年录取分数和招生计划数据
     * @param profile 用户个人信息
     * @param levelTypes 要返回的等级类型列表，为空时默认返回所有等级
     * @return 所有适合的专业列表
     */
    public Map<String, Object> getAllSuitableMajors(UserProfileInfo profile, List<String> levelTypes) {
        long startTime = System.currentTimeMillis();

        // 处理 levelTypes 参数，默认返回所有等级
        Set<String> requestedLevels = new HashSet<>();
        if (levelTypes == null || levelTypes.isEmpty()) {
            requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            log.info("未指定等级类型，默认返回所有等级数据");
        } else {
            requestedLevels.addAll(levelTypes);
            log.info("用户请求的等级类型：{}", requestedLevels);
        }

        log.info("开始获取所有适合专业（优化版本），用户省份：{}，分数：{}，选科：{}，意向专业：{}，请求等级：{}",
                profile.getProvince(), profile.getTotalScore(), profile.getSubjects(), profile.getInterestedMajorCategories(), requestedLevels);

        Map<String, Object> result = new HashMap<>();
        StringBuilder queryInfo = new StringBuilder();
        List<MajorAdmissionInfo> rushMajors = new ArrayList<>();
        List<MajorAdmissionInfo> stableMajors = new ArrayList<>();
        List<MajorAdmissionInfo> safeMajors = new ArrayList<>();

        try {
            // 第一步：从专业录取分数线中获取对应的数据
            List<MajorAdmissionInfo> admissionInfos = queryMajorAdmissionDataByConditions(profile);
            log.info("第一步：从专业录取分数线中获取得到 {} 条数据", admissionInfos.size());

            if (admissionInfos.isEmpty()) {
                return buildEmptyAllSuitableResult(profile, queryInfo);
            }

            // 第二步：过滤招生计划
            List<MajorAdmissionInfo> filteredMajors = batchFilterEnrollmentPlansOptimized(admissionInfos, profile);
            log.info("第二步：过滤招生计划后剩余 {} 条数据", filteredMajors.size());

            if (filteredMajors.isEmpty()) {
                return buildEmptyAllSuitableResult(profile, queryInfo);
            }

            // 第三步：按冲稳保分组
            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByScore(filteredMajors, profile.getTotalScore());

            rushMajors = classifiedMajors.get("rush");
            stableMajors = classifiedMajors.get("stable");
            safeMajors = classifiedMajors.get("safe");

            log.info("第三步：专业分组完成 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                    rushMajors.size(), stableMajors.size(), safeMajors.size());

            // 第四步：按需查询近三年专业录取分数数据和招生计划数据
            if (requestedLevels.contains("rush") && !rushMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(rushMajors, profile);
                batchQueryThreeYearsEnrollmentPlans(rushMajors, profile);
                log.info("为冲刺等级查询近三年数据完成");
            }
            if (requestedLevels.contains("stable") && !stableMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(stableMajors, profile);
                batchQueryThreeYearsEnrollmentPlans(stableMajors, profile);
                log.info("为稳妥等级查询近三年数据完成");
            }
            if (requestedLevels.contains("safe") && !safeMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(safeMajors, profile);
                batchQueryThreeYearsEnrollmentPlans(safeMajors, profile);
                log.info("为保底等级查询近三年数据完成");
            }
            log.info("第四步：按需查询近三年专业录取分数和招生计划数据完成");

            // 构建查询信息说明
            buildQueryInfoForAllSuitableWithClassification(profile, rushMajors, stableMajors, safeMajors, queryInfo);

        } catch (Exception e) {
            log.error("获取所有适合专业过程中发生异常", e);
            return buildErrorAllSuitableResult(e.getMessage());
        }

        // 构建返回结果，根据请求的等级过滤数据
        result.put("rushMajors", requestedLevels.contains("rush") ? rushMajors : new ArrayList<>());
        result.put("stableMajors", requestedLevels.contains("stable") ? stableMajors : new ArrayList<>());
        result.put("safeMajors", requestedLevels.contains("safe") ? safeMajors : new ArrayList<>());
        result.put("rushCount",rushMajors.size());
        result.put("stableCount",  stableMajors.size());
        result.put("safeCount", safeMajors.size());

        int totalCount = 0;
        if (requestedLevels.contains("rush")) {
            totalCount += rushMajors.size();
        }
        if (requestedLevels.contains("stable")) {
            totalCount += stableMajors.size();
        }
        if (requestedLevels.contains("safe")) {
            totalCount += safeMajors.size();
        }

        result.put("totalCount", totalCount);
        result.put("queryInfo", queryInfo.toString());
        result.put("requestedLevels", new ArrayList<>(requestedLevels)); // 返回请求的等级信息

        long endTime = System.currentTimeMillis();
        log.info("获取所有适合专业完成（优化版本），总耗时: {}ms，总专业数: {}，请求等级: {}",
                endTime - startTime, totalCount, requestedLevels);

        return result;
    }

    /**
     * 扩大分数范围查询所有候选专业数据
     */
    private List<MajorAdmissionInfo> queryAllCandidateMajorsWithExtendedRange(UserProfileInfo profile) {
        // 使用用户设置的分数范围，如果没有设置则使用扩大的默认值
        int minScore;
        int maxScore;

        if (profile.getMinScore() != null) {
            minScore = profile.getMinScore();
            log.info("使用用户自定义最低分数: {}", minScore);
        } else {
            minScore = profile.getTotalScore() - 100; // 扩大的默认值：用户分数减100
            log.info("使用扩大的默认最低分数: {} (用户分数-100)", minScore);
        }

        if (profile.getMaxScore() != null) {
            maxScore = profile.getMaxScore();
            log.info("使用用户自定义最高分数: {}", maxScore);
        } else {
            maxScore = profile.getTotalScore() + 50; // 扩大的默认值：用户分数加50
            log.info("使用扩大的默认最高分数: {} (用户分数+50)", maxScore);
        }

        List<MajorAdmissionDO> admissionDOList;
        if (profile.getTypeName() != null && !profile.getTypeName().isEmpty()) {
            admissionDOList = majorAdmissionService.getMajorAdmissionByProvinceYearScoreRangeAndType(
                    profile.getProvince(), 2024, minScore, maxScore, profile.getTypeName());
        } else {
            admissionDOList = majorAdmissionService.getMajorAdmissionByProvinceYearAndScoreRange(
                    profile.getProvince(), 2024, minScore, maxScore);
        }

        return convertToMajorAdmissionInfoList(admissionDOList);
    }

    /**
     * 优化版本：查询候选专业数据（重构版本：先读招生计划表）
     * @deprecated 使用 filterEnrollmentPlansByConditions + queryAdmissionScoresByEnrollmentPlans 替代
     */
    @Deprecated
    private List<MajorAdmissionInfo> queryAllCandidateMajorsOptimized(UserProfileInfo profile) {
        log.warn("使用了已废弃的 queryAllCandidateMajorsOptimized 方法，建议使用新的重构方法");

        // 使用新的重构流程
        List<CollegeEnrollmentPlanDO> enrollmentPlans = filterEnrollmentPlansByConditions(profile);
        return queryAdmissionScoresByEnrollmentPlans(enrollmentPlans, profile);
    }

    /**
     * 最优化版本：在数据库查询时就进行兴趣专业匹配（重构版本：先读招生计划表）
     * @deprecated 使用 filterEnrollmentPlansByConditions + queryAdmissionScoresByEnrollmentPlans 替代
     */
    @Deprecated
    private List<MajorAdmissionInfo> queryAllCandidateMajorsWithInterestMatching(UserProfileInfo profile) {
        log.warn("使用了已废弃的 queryAllCandidateMajorsWithInterestMatching 方法，建议使用新的重构方法");

        // 使用新的重构流程
        List<CollegeEnrollmentPlanDO> enrollmentPlans = filterEnrollmentPlansByConditions(profile);
        return queryAdmissionScoresByEnrollmentPlans(enrollmentPlans, profile);
    }

    /**
     * 根据关键词在数据库中查询专业数据
     */
    private List<MajorAdmissionDO> queryByKeywordInDatabase(String provinceName, Integer year,
            Integer minScore, Integer maxScore, String typeName, String keyword) {
        try {
            if (typeName != null && !typeName.isEmpty()) {
                return majorAdmissionMapper.selectByProvinceYearScoreRangeAndMajorKeywords(
                        provinceName, year, minScore, maxScore, keyword);
            } else {
                return majorAdmissionMapper.selectByProvinceYearScoreRangeAndMajorName(
                        provinceName, year, minScore, maxScore, keyword);
            }
        } catch (Exception e) {
            log.warn("关键词查询失败: {}", keyword, e);
            return new ArrayList<>();
        }
    }

    /**
     * 简化版选科筛选（主要的选科筛选已在招生计划过滤中完成）
     * 这里只做基本的选科要求检查，避免重复筛选
     */
    private List<MajorAdmissionInfo> filterBySubjectSelectionSimple(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return new ArrayList<>();
        }

        // 如果用户没有选科信息，直接返回
        if (profile.getSubjects() == null || profile.getSubjects().isEmpty()) {
            log.info("用户未提供选科信息，跳过选科筛选");
            return majors;
        }

        Set<String> userSubjects = new HashSet<>(profile.getSubjects());
        log.debug("用户选科信息: {}", userSubjects);

        // 简化版筛选：只检查录取数据中的选科要求，招生计划的选科要求已在前面处理过
        List<MajorAdmissionInfo> filteredMajors = majors.stream()
                .filter(major -> {
                    // 检查专业录取数据中的选科要求
                    if (major.getSubjectSelection() != null && !major.getSubjectSelection().isEmpty()) {
                        return checkSubjectRequirements(userSubjects, major.getSubjectSelection());
                    }
                    // 如果没有选科要求，则通过筛选
                    return true;
                })
                .collect(Collectors.toList());

        log.debug("简化选科筛选完成，原始数量: {}, 筛选后数量: {}", majors.size(), filteredMajors.size());
        return filteredMajors;
    }

    /**
     * 仅进行选科筛选（兴趣匹配已在数据库查询时完成）
     */
    private List<MajorAdmissionInfo> filterBySubjectSelectionOnly(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return new ArrayList<>();
        }

        // 如果用户没有选科信息，直接返回
        if (profile.getSubjects() == null || profile.getSubjects().isEmpty()) {
            log.info("用户未提供选科信息，跳过选科筛选");
            return majors;
        }

        log.info("开始进行选科筛选，原始专业数量: {}", majors.size());

        // 根据学生选科筛选数据（简化版本，因为主要的选科筛选已在招生计划过滤中完成）
        List<MajorAdmissionInfo> filteredMajors = filterBySubjectSelectionSimple(majors, profile);

        log.info("选科筛选完成，筛选后专业数量: {}", filteredMajors.size());
        return filteredMajors;
    }

    /**
     * 优化版本：批量过滤招生计划数据（单次查询多年份）
     */
    private List<MajorAdmissionInfo> batchFilterEnrollmentPlansOptimized(List<MajorAdmissionInfo> admissionList, UserProfileInfo profile) {
        if (admissionList == null || admissionList.isEmpty()) {
            return new ArrayList<>();
        }

        long startTime = System.currentTimeMillis();
        log.info("开始优化批量过滤招生计划，总数量: {}", admissionList.size());

        try {
            // 提取所有不重复的学校名称和专业名称
            List<String> schoolNames = admissionList.stream()
                    .map(MajorAdmissionInfo::getSchoolName)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            List<String> majorNames = admissionList.stream()
                    .map(MajorAdmissionInfo::getMajorName)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            log.info("提取到 {} 个不重复学校名称，{} 个不重复专业名称", schoolNames.size(), majorNames.size());

            // 优化：使用多年份查询，一次性获取2022-2024年的数据
            List<CollegeEnrollmentPlanDO> existingPlans = collegeEnrollmentPlanService
                    .batchCheckEnrollmentPlansMultiYear(schoolNames, majorNames, profile.getProvince());

            log.info("数据库中找到{}个有招生计划的学校专业组合（多年份）", existingPlans.size());

            // 获取用户选科信息
            Set<String> userSubjects = new HashSet<>();
            if (profile.getSubjects() != null && !profile.getSubjects().isEmpty()) {
                userSubjects.addAll(profile.getSubjects());
            }

            // 构建符合选科要求且有招生计划的学校专业组合集合
            Set<String> validCombinations = new HashSet<>();
            for (CollegeEnrollmentPlanDO plan : existingPlans) {
                // 检查选科要求
                if (userSubjects.isEmpty() || checkSubjectRequirements(userSubjects, plan.getCourseSelectionRequirements())) {
                    String combination = plan.getSchoolName() + ":" + plan.getCollegeMajorName();
                    validCombinations.add(combination);
                }
            }

            log.info("符合选科要求的招生计划组合: {}", validCombinations.size());

            // 过滤出有招生计划且符合选科要求的专业
            List<MajorAdmissionInfo> filteredList = admissionList.stream()
                    .filter(admission -> {
                        // 检查是否有匹配的招生计划（支持括号内容匹配）
                        for (String combination : validCombinations) {
                            String[] parts = combination.split(":", 2);
                            if (parts.length == 2 && parts[0].equals(admission.getSchoolName())) {
                                String planMajorName = parts[1];
                                if (isMajorNameMatch(admission.getMajorName(), planMajorName)) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            long endTime = System.currentTimeMillis();
            log.info("优化批量过滤完成，原始数量: {}, 过滤后数量: {}, 耗时: {}ms",
                     admissionList.size(), filteredList.size(), endTime - startTime);

            return filteredList;

        } catch (Exception e) {
            log.error("优化批量过滤招生计划数据失败", e);
            return admissionList; // 发生异常时返回原始列表
        }
    }

    /**
     * 优化版本：兴趣匹配和选科筛选（在更小的数据集上操作）
     */
    private List<MajorAdmissionInfo> filterAndMatchMajorsOptimized(List<MajorAdmissionInfo> allCandidateMajors, UserProfileInfo profile) {
        List<MajorAdmissionInfo> matchedMajors = new ArrayList<>();
        Set<String> interestedCategories = new HashSet<>();

        // 如果用户有意向专业，进行兴趣匹配
        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            interestedCategories.addAll(profile.getInterestedMajorCategories());

            // 优化：使用并行流处理大量数据
            matchedMajors = allCandidateMajors.parallelStream()
                    .filter(major -> {
                        // 检查是否匹配感兴趣的专业类别
                        for (String category : interestedCategories) {
                            if (major.getMajorName() != null && major.getMajorName().contains(category)) {
                                return true;
                            }
                            // 关键词匹配
                            List<String> keywords = splitMajorNameToKeywords(category);
                            for (String keyword : keywords) {
                                if (major.getMajorName() != null && major.getMajorName().contains(keyword)) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            log.info("优化兴趣匹配后的专业数量: {}", matchedMajors.size());
        } else {
            // 如果没有意向专业，返回所有候选专业
            matchedMajors = allCandidateMajors;
            log.info("用户未指定意向专业，返回所有候选专业: {}", matchedMajors.size());
        }

        // 根据学生选科筛选数据（已经在招生计划过滤中处理过了，这里可以简化）
        return matchedMajors;
    }

    /**
     * 为获取所有适合专业进行兴趣匹配和选科筛选（不限制数量）
     */
    private List<MajorAdmissionInfo> filterAndMatchMajorsForAllSuitable(List<MajorAdmissionInfo> allCandidateMajors, UserProfileInfo profile) {
        List<MajorAdmissionInfo> matchedMajors = new ArrayList<>();
        Set<String> interestedCategories = new HashSet<>();

        // 如果用户有意向专业，进行兴趣匹配
        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            interestedCategories.addAll(profile.getInterestedMajorCategories());

            for (MajorAdmissionInfo major : allCandidateMajors) {
                // 检查是否匹配感兴趣的专业类别
                boolean isMatched = false;
                for (String category : interestedCategories) {
                    if (major.getMajorName() != null && major.getMajorName().contains(category)) {
                        isMatched = true;
                        break;
                    }
                    // 关键词匹配
                    List<String> keywords = splitMajorNameToKeywords(category);
                    for (String keyword : keywords) {
                        if (major.getMajorName() != null && major.getMajorName().contains(keyword)) {
                            isMatched = true;
                            break;
                        }
                    }
                    if (isMatched) {
                        break;
                    }
                }

                if (isMatched) {
                    matchedMajors.add(major);
                }
            }

            log.info("兴趣匹配后的专业数量: {}", matchedMajors.size());
        } else {
            // 如果没有意向专业，返回所有候选专业
            matchedMajors = allCandidateMajors;
            log.info("用户未指定意向专业，返回所有候选专业: {}", matchedMajors.size());
        }

        // 根据学生选科筛选数据（简化版本，因为主要的选科筛选已在招生计划过滤中完成）
        return filterBySubjectSelectionSimple(matchedMajors, profile);
    }

    /**
     * 按冲稳保分类专业
     * @param majors 专业列表
     * @param userScore 用户分数
     * @return 分类后的专业Map
     */
    private Map<String, List<MajorAdmissionInfo>> classifyMajorsByRushStableSafe(List<MajorAdmissionInfo> majors, int userScore) {
        Map<String, List<MajorAdmissionInfo>> result = new HashMap<>();
        List<MajorAdmissionInfo> rushMajors = new ArrayList<>();    // 冲刺：分数高于用户分数
        List<MajorAdmissionInfo> stableMajors = new ArrayList<>();  // 稳妥：分数接近用户分数
        List<MajorAdmissionInfo> safeMajors = new ArrayList<>();    // 保底：分数低于用户分数

        for (MajorAdmissionInfo major : majors) {
            try {
                int majorScore = Integer.parseInt(major.getLowestScore());
                int scoreDiff = majorScore - userScore;

                if (scoreDiff > 5) {
                    // 冲刺：专业分数比用户分数高5分以上
                    rushMajors.add(major);
                } else if (scoreDiff >= -5 && scoreDiff <= 5) {
                    // 稳妥：专业分数在用户分数±5分范围内
                    stableMajors.add(major);
                } else if (scoreDiff < -5) {
                    // 保底：专业分数比用户分数低5分以上
                    safeMajors.add(major);
                }
            } catch (NumberFormatException e) {
                // 无法解析分数的专业放入稳妥类别
                stableMajors.add(major);
                log.warn("无法解析专业分数: {} - {}", major.getSchoolName(), major.getMajorName());
            }
        }

        // 按分数排序
        Comparator<MajorAdmissionInfo> scoreComparator = (m1, m2) -> {
            try {
                int score1 = Integer.parseInt(m1.getLowestScore());
                int score2 = Integer.parseInt(m2.getLowestScore());
                return Integer.compare(score1, score2);
            } catch (NumberFormatException e) {
                return 0;
            }
        };

        rushMajors.sort(scoreComparator);
        stableMajors.sort(scoreComparator);
        safeMajors.sort(scoreComparator);

        result.put("rush", rushMajors);
        result.put("stable", stableMajors);
        result.put("safe", safeMajors);

        log.info("专业分类完成 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                rushMajors.size(), stableMajors.size(), safeMajors.size());

        return result;
    }



    /**
     * 批量查询近三年招生计划数据（多线程逐个查询版本，避免笛卡尔积问题）
     * @param majors 专业列表
     * @param profile 用户信息
     */
    private void batchQueryThreeYearsEnrollmentPlans(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return;
        }

        // 添加数据量检查，防止内存溢出
        if (majors.size() > 10000) {
            log.warn("专业数据量过大，可能影响性能：{}个专业，建议分批处理", majors.size());
        }

        log.info("开始为 {} 个专业使用多线程逐个查询近三年招生计划数据", majors.size());

        try {
            // 定义查询的年份（近三年）
            List<Integer> years = Arrays.asList(2025, 2024, 2023, 2022);

            // 创建线程池，控制并发数量
            int threadPoolSize = Math.min(10, Math.max(2, majors.size() / 50)); // 根据专业数量动态调整线程数
            ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);

            log.info("使用 {} 个线程并行查询招生计划数据", threadPoolSize);

            try {
                // 使用并行流提高查询效率，为每个专业创建查询任务
                List<CompletableFuture<Void>> futures = majors.stream()
                        .map(major -> CompletableFuture.runAsync(() -> {
                            try {
                                // 为当前专业查询近三年招生计划数据
                                List<CollegeEnrollmentPlanInfo> allEnrollmentPlans = new ArrayList<>();

                                for (Integer year : years) {
                                    try {
                                        // 使用现有的单个专业查询方法，避免笛卡尔积问题
                                        List<CollegeEnrollmentPlanInfo> yearPlans = queryEnrollmentPlanForMajorAndYear(major, profile, year);
                                        if (yearPlans != null && !yearPlans.isEmpty()) {
                                            allEnrollmentPlans.addAll(yearPlans);
                                            log.debug("专业 {} - {} 在 {} 年找到 {} 条招生计划数据",
                                                    major.getSchoolName(), major.getMajorName(), year, yearPlans.size());
                                        }
                                    } catch (Exception e) {
                                        log.warn("查询专业 {} - {} 在 {} 年的招生计划数据失败: {}",
                                                major.getSchoolName(), major.getMajorName(), year, e.getMessage());
                                    }
                                }

                                // 设置查询到的招生计划数据
                                if (!allEnrollmentPlans.isEmpty()) {
                                    // 去重处理（按年份、批次等去重）
                                    List<CollegeEnrollmentPlanInfo> deduplicatedPlans = deduplicateEnrollmentPlans(allEnrollmentPlans);
                                    
                                    // 过滤掉国家专项计划和提前批数据
                                    List<CollegeEnrollmentPlanInfo> filteredPlans = deduplicatedPlans.stream()
                                            .filter(plan -> {
                                                String batchName = plan.getBatchName();
                                                if (batchName == null || batchName.trim().isEmpty()) {
                                                    return true; // 保留没有批次信息的招生计划
                                                }
                                                // 过滤掉包含"国家专项"或"提前批"的招生计划
                                                return !batchName.contains("国家专项") && !batchName.contains("提前批");
                                            })
                                            .collect(Collectors.toList());
                                    
                                    if (!filteredPlans.isEmpty()) {
                                        major.setEnrollmentPlanData(filteredPlans);
                                        log.debug("专业 {} - {} 总共找到 {} 条近三年招生计划数据（去重并过滤后）",
                                                major.getSchoolName(), major.getMajorName(), filteredPlans.size());
                                    } else {
                                        log.debug("专业 {} - {} 的招生计划数据全部被过滤，未设置招生计划数据",
                                                major.getSchoolName(), major.getMajorName());
                                    }
                                } else {
                                    log.debug("专业 {} - {} 未找到近三年招生计划数据",
                                            major.getSchoolName(), major.getMajorName());
                                }

                            } catch (Exception e) {
                                log.error("查询专业 {} - {} 的招生计划数据时发生异常: {}",
                                        major.getSchoolName(), major.getMajorName(), e.getMessage(), e);
                            }
                        }, executorService))
                        .collect(Collectors.toList());

                // 等待所有查询完成，设置超时时间为60秒
                CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
                allFutures.get(60, TimeUnit.SECONDS);

                // 统计查询结果
                int foundCount = (int) majors.stream()
                        .filter(major -> major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty())
                        .count();

                log.info("完成 {} 个专业的近三年招生计划数据查询，其中 {} 个专业有招生计划数据",
                        majors.size(), foundCount);

            } finally {
                // 关闭线程池
                executorService.shutdown();
                try {
                    if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
                        executorService.shutdownNow();
                    }
                } catch (InterruptedException e) {
                    executorService.shutdownNow();
                    Thread.currentThread().interrupt();
                }
            }

        } catch (TimeoutException e) {
            log.error("批量查询近三年招生计划数据超时", e);
        } catch (Exception e) {
            log.error("批量查询近三年招生计划数据失败", e);
        }
    }

    /**
     * 查询指定专业和年份的招生计划数据
     * @param major 专业信息
     * @param profile 用户信息
     * @param year 年份
     * @return 招生计划数据列表
     */
    private List<CollegeEnrollmentPlanInfo> queryEnrollmentPlanForMajorAndYear(MajorAdmissionInfo major, UserProfileInfo profile, Integer year) {
        try {
            // 使用现有的招生计划查询服务
            return collegeEnrollmentPlanService.getEnrollmentPlanForMajor(
                    major.getSchoolName(),
                    major.getMajorName(),
                    profile.getProvince(),
                    profile.getTypeName(),
                    year);
        } catch (Exception e) {
            log.warn("查询专业 {} - {} 在 {} 年的招生计划数据失败: {}",
                    major.getSchoolName(), major.getMajorName(), year, e.getMessage());
            return null;
        }
    }

    /**
     * 去重招生计划数据
     * 按照年份、批次、专业组等关键字段去重，保留最新的数据
     * @param enrollmentPlans 招生计划数据列表
     * @return 去重后的招生计划数据列表
     */
    private List<CollegeEnrollmentPlanInfo> deduplicateEnrollmentPlans(List<CollegeEnrollmentPlanInfo> enrollmentPlans) {
        if (enrollmentPlans == null || enrollmentPlans.isEmpty()) {
            return enrollmentPlans;
        }

        // 使用Map进行去重，key为去重标识，value为招生计划数据
        Map<String, CollegeEnrollmentPlanInfo> deduplicationMap = new LinkedHashMap<>();

        for (CollegeEnrollmentPlanInfo plan : enrollmentPlans) {
            // 构建去重key：年份 + 批次 + 专业组代码 + 专业组名称
            String deduplicationKey = String.format("%d_%s_%s_%s",
                    plan.getYear() != null ? plan.getYear() : 0,
                    plan.getBatchName() != null ? plan.getBatchName() : "",
                    plan.getSpecialCode() != null ? plan.getSpecialCode() : "",
                    plan.getSpecialGroupName() != null ? plan.getSpecialGroupName() : ""
            );

            // 如果已存在相同key的数据，比较并保留更完整的数据
            if (deduplicationMap.containsKey(deduplicationKey)) {
                CollegeEnrollmentPlanInfo existingPlan = deduplicationMap.get(deduplicationKey);
                // 比较招生人数，保留有招生人数的数据，或者招生人数更大的数据
                Integer existingNumbers = parseEnrollmentNumbers(existingPlan.getEnrollmentNumbers());
                Integer planNumbers = parseEnrollmentNumbers(plan.getEnrollmentNumbers());

                if ((existingNumbers == null || existingNumbers == 0) && (planNumbers != null && planNumbers > 0)) {
                    deduplicationMap.put(deduplicationKey, plan);
                } else if (planNumbers != null && existingNumbers != null && planNumbers > existingNumbers) {
                    deduplicationMap.put(deduplicationKey, plan);
                }
            } else {
                deduplicationMap.put(deduplicationKey, plan);
            }
        }

        // 转换为列表并按年份倒序排列
        List<CollegeEnrollmentPlanInfo> result = new ArrayList<>(deduplicationMap.values());
        result.sort((a, b) -> {
            // 首先按年份倒序排列
            int yearCompare = Integer.compare(
                    b.getYear() != null ? b.getYear() : 0,
                    a.getYear() != null ? a.getYear() : 0
            );
            if (yearCompare != 0) {
                return yearCompare;
            }
            // 然后按批次名称排序
            String batchA = a.getBatchName() != null ? a.getBatchName() : "";
            String batchB = b.getBatchName() != null ? b.getBatchName() : "";
            return batchA.compareTo(batchB);
        });

        return result;
    }

    /**
     * 过滤掉近三年无招生计划的专业
     * @param majors 专业列表
     * @return 有招生计划的专业列表
     */
    private List<MajorAdmissionInfo> filterMajorsWithEnrollmentPlans(List<MajorAdmissionInfo> majors) {
        if (majors == null || majors.isEmpty()) {
            return majors;
        }

        List<MajorAdmissionInfo> majorsWithPlans = new ArrayList<>();
        int filteredCount = 0;

        for (MajorAdmissionInfo major : majors) {
            // 检查专业是否有招生计划数据
            if (major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty()) {
                majorsWithPlans.add(major);
            } else {
                filteredCount++;
                log.debug("过滤掉无招生计划的专业: {} - {}", major.getSchoolName(), major.getMajorName());
            }
        }

        if (filteredCount > 0) {
            log.info("过滤掉 {} 个近三年无招生计划的专业，保留 {} 个有招生计划的专业",
                    filteredCount, majorsWithPlans.size());
        }

        return majorsWithPlans;
    }

    /**
     * 多线程查询近三年专业录取分数数据（为每个专业单独查询）
     * @param majors 专业列表
     * @param profile 用户信息
     */
    private void batchQueryThreeYearsAdmissionScores(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return;
        }

        long startTime = System.currentTimeMillis();
        log.info("开始为 {} 个专业使用多线程查询近三年录取分数数据", majors.size());

        // 添加数据量检查，防止内存溢出
        if (majors.size() > 10000) {
            log.warn("专业数据量过大，可能影响性能：{}个专业，建议分批处理", majors.size());
        }

        try {
            // 定义查询的年份（近四年）
            List<Integer> years = Arrays.asList(2025, 2024, 2023);

            // 使用原子计数器来统计成功数量（线程安全）
            AtomicInteger successCount = new AtomicInteger(0);
            AtomicInteger processedCount = new AtomicInteger(0);

            // 创建并发任务列表
            List<CompletableFuture<Void>> futures = new ArrayList<>();

            // 为每个专业创建一个异步查询任务
            for (int i = 0; i < majors.size(); i++) {
                final int index = i;
                final MajorAdmissionInfo major = majors.get(i);

                if (major.getSchoolUUID() == null || major.getMajorName() == null) {
                    log.debug("专业 {} 的学校UUID或专业名称为空，跳过", index + 1);
                    continue;
                }

                // 创建异步任务
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    try {
                        // 查询近三年的录取分数数据
                        List<MajorAdmissionInfo.HistoricalYearData> allHistoricalData = new ArrayList<>();

                        for (Integer year : years) {
                            try {
                                // 使用现有的单个专业查询方法
                                List<MajorAdmissionInfo.HistoricalYearData> yearData = queryAdmissionScoreForMajorAndYear(major, profile, year);
                                if (yearData != null && !yearData.isEmpty()) {
                                    allHistoricalData.addAll(yearData);
                                    log.debug("专业 {} - {} 在 {} 年找到 {} 条录取分数数据",
                                            major.getSchoolName(), major.getMajorName(), year, yearData.size());
                                }
                            } catch (Exception e) {
                                log.warn("查询专业 {} - {} 在 {} 年的录取分数数据失败: {}",
                                        major.getSchoolName(), major.getMajorName(), year, e.getMessage());
                            }
                        }

                        // 去重处理
                        if (!allHistoricalData.isEmpty()) {
                            Set<MajorAdmissionInfo.HistoricalYearData> uniqueDataSet = new HashSet<>();
                            List<MajorAdmissionInfo.HistoricalYearData> deduplicatedData = new ArrayList<>();

                            for (MajorAdmissionInfo.HistoricalYearData historicalData : allHistoricalData) {
                                if (historicalData != null && uniqueDataSet.add(historicalData)) {
                                    deduplicatedData.add(historicalData);
                                }
                            }

                            if (!deduplicatedData.isEmpty()) {
                                major.setHistoricalData(deduplicatedData);
                                successCount.incrementAndGet();
                                log.debug("专业 {}/{}: {} - {} 设置了 {} 条近三年录取分数数据",
                                        index + 1, majors.size(), major.getSchoolName(), major.getMajorName(), deduplicatedData.size());
                            }
                        } else {
                            log.debug("专业 {}/{}: {} - {} 未找到近三年录取分数数据",
                                    index + 1, majors.size(), major.getSchoolName(), major.getMajorName());
                        }

                    } catch (Exception e) {
                        log.warn("查询专业 {} - {} 的录取分数数据失败: {}",
                                major.getSchoolName(), major.getMajorName(), e.getMessage());
                    } finally {
                        // 更新处理计数并输出进度
                        int processed = processedCount.incrementAndGet();
                        if (processed % 100 == 0) {
                            log.info("已处理 {}/{} 个专业，成功查询到数据的专业数量: {}",
                                    processed, majors.size(), successCount.get());
                        }
                    }
                }, executorService); // 使用现有的线程池

                futures.add(future);
            }

            // 等待所有任务完成，设置超时时间
            try {
                CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
                allFutures.get(5, TimeUnit.MINUTES); // 设置5分钟超时

                log.info("所有录取分数查询任务完成");
            } catch (TimeoutException e) {
                log.warn("录取分数查询任务超时，已完成的任务将保留结果");
                // 取消未完成的任务
                futures.forEach(future -> future.cancel(true));
            }

            long endTime = System.currentTimeMillis();
            log.info("多线程查询近三年录取分数数据完成，耗时: {}ms，成功设置数据的专业数量: {}/{}",
                    endTime - startTime, successCount.get(), majors.size());

        } catch (Exception e) {
            log.error("多线程查询近三年录取分数数据失败", e);
        }
    }

    /**
     * 查询指定专业和年份的录取分数数据
     * @param major 专业信息
     * @param profile 用户信息
     * @param year 年份
     * @return 历史录取分数数据列表
     */
    private List<MajorAdmissionInfo.HistoricalYearData> queryAdmissionScoreForMajorAndYear(MajorAdmissionInfo major, UserProfileInfo profile, Integer year) {
        try {
            // 根据查询年份动态确定对应的科目类型名称
            String typeNameForYear = determineTypeNameForYear(profile, year);

            log.debug("查询专业 {} - {} 在 {} 年的录取分数数据，使用科目类型: {}",
                    major.getSchoolName(), major.getMajorName(), year, typeNameForYear);

            // 使用现有的专业录取数据查询服务
            List<MajorAdmissionDO> admissionDOList = majorAdmissionService.getMajorAdmissionBySchoolMajorYearTypeNameprovinceName(
                    major.getSchoolUUID(),
                    major.getMajorName(),
                    year,
                    typeNameForYear,
                    profile.getProvince()
            );

            if (admissionDOList != null && !admissionDOList.isEmpty()) {
                // 转换为历史数据对象列表
                return admissionDOList.stream()
                        .map(this::convertToHistoricalYearData)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
            }

            return null;
        } catch (Exception e) {
            log.warn("查询专业 {} - {} 在 {} 年的录取分数数据失败: {}",
                    major.getSchoolName(), major.getMajorName(), year, e.getMessage());
            return null;
        }
    }

    /**
     * 构建录取数据的分组键，包含所有可能影响数据唯一性的字段
     * 避免数据丢失，确保不同年份、批次、类型、选科要求的数据能够正确分组
     *
     * @param admission 录取数据对象
     * @return 分组键字符串
     */
    private String buildAdmissionDataKey(MajorAdmissionDO admission) {
        StringBuilder keyBuilder = new StringBuilder();

        // 基础信息：学校UUID + 专业名称
        keyBuilder.append(admission.getSchoolUuid()).append(":");
        keyBuilder.append(admission.getMajorName()).append(":");

        // 年份信息（必须包含，避免不同年份数据混合）
        keyBuilder.append(admission.getYear() != null ? admission.getYear() : "null").append(":");

        // 批次信息（重要：同一专业可能有多个批次）
        keyBuilder.append(admission.getBatchName() != null ? admission.getBatchName() : "null").append(":");

        // 类型信息（重要：物理类、历史类等）
        keyBuilder.append(admission.getTypeName() != null ? admission.getTypeName() : "null").append(":");

        // 选科组合（重要：不同选科要求可能有不同分数线）
        keyBuilder.append(admission.getSubjectGroup() != null ? admission.getSubjectGroup() : "null");

        return keyBuilder.toString();
    }

    /**
     * 查找匹配的录取数据，支持多种分组键的匹配
     * 修复数据丢失问题：采用更宽松的匹配策略，确保不遗漏任何相关数据
     *
     * @param allAdmissionData 所有录取数据的分组Map
     * @param major 专业信息
     * @param profile 用户信息
     * @return 匹配的录取数据列表
     */
    private List<MajorAdmissionDO> findMatchingAdmissionData(Map<String, List<MajorAdmissionDO>> allAdmissionData,
                                                           MajorAdmissionInfo major, UserProfileInfo profile) {
        List<MajorAdmissionDO> result = new ArrayList<>();
        Set<String> addedKeys = new HashSet<>(); // 防止重复添加相同的数据

        log.debug("开始查找匹配数据 - 学校: {}, 专业: {}, 用户类型: {}",
                major.getSchoolUUID(), major.getMajorName(), profile.getTypeName());

        // 遍历所有分组，找到匹配的数据
        for (Map.Entry<String, List<MajorAdmissionDO>> entry : allAdmissionData.entrySet()) {
            String key = entry.getKey();
            List<MajorAdmissionDO> admissionList = entry.getValue();

            // 解析分组键
            String[] keyParts = key.split(":");
            if (keyParts.length >= 2) {
                String schoolUuid = keyParts[0];
                String majorName = keyParts[1];

                // 基础匹配：学校UUID和专业名称（必须完全匹配）
                if (schoolUuid.equals(major.getSchoolUUID()) && majorName.equals(major.getMajorName())) {
                    boolean shouldInclude = false;
                    String matchReason = "";

                    // 策略1：如果分组键长度不足5，直接包含（兼容旧格式）
                    if (keyParts.length < 5) {
                        shouldInclude = true;
                        matchReason = "兼容旧格式";
                    } else {
                        // 策略2：检查类型匹配
                        String keyTypeName = keyParts[4];

                        // 如果分组键中的类型为null或空，或者与用户类型匹配，则包含
                        if ("null".equals(keyTypeName) || keyTypeName.trim().isEmpty()) {
                            shouldInclude = true;
                            matchReason = "分组键类型为空";
                        } else if (profile.getTypeName() != null && keyTypeName.equals(profile.getTypeName())) {
                            shouldInclude = true;
                            matchReason = "类型完全匹配";
                        } else if (profile.getTypeName() == null) {
                            // 如果用户类型为空，也包含这些数据
                            shouldInclude = true;
                            matchReason = "用户类型为空";
                        }

                        // 策略3：如果上述条件都不满足，但是是同一学校同一专业，仍然包含
                        // 这是为了防止因为类型不匹配而丢失重要的历史数据
                        if (!shouldInclude) {
                            shouldInclude = true;
                            matchReason = "同校同专业保底策略";
                            log.debug("使用保底策略包含数据 - 分组键类型: {}, 用户类型: {}", keyTypeName, profile.getTypeName());
                        }
                    }

                    if (shouldInclude && !addedKeys.contains(key)) {
                        result.addAll(admissionList);
                        addedKeys.add(key);
                        log.debug("匹配成功 - 分组键: {}, 数据条数: {}, 匹配原因: {}",
                                key, admissionList.size(), matchReason);
                    }
                }
            }
        }

        log.debug("查找完成 - 学校: {}, 专业: {}, 找到数据: {} 条, 匹配的分组: {} 个",
                major.getSchoolUUID(), major.getMajorName(), result.size(), addedKeys.size());

        return result;
    }

    /**
     * 增强版查找匹配的录取数据方法
     * 使用多重匹配策略，确保最大程度地避免数据丢失
     *
     * @param allAdmissionData 所有录取数据的分组Map
     * @param major 专业信息
     * @param profile 用户信息
     * @return 匹配的录取数据列表
     */
    private List<MajorAdmissionDO> findMatchingAdmissionDataEnhanced(Map<String, List<MajorAdmissionDO>> allAdmissionData,
                                                                   MajorAdmissionInfo major, UserProfileInfo profile) {
        List<MajorAdmissionDO> result = new ArrayList<>();
        Set<Long> addedIds = new HashSet<>(); // 使用ID去重，防止重复添加相同的记录

        // 第一轮：精确匹配（学校UUID + 专业名称 + 类型）
        List<MajorAdmissionDO> exactMatches = findExactMatches(allAdmissionData, major, profile);
        for (MajorAdmissionDO admission : exactMatches) {
            if (admission.getId() != null && addedIds.add(admission.getId())) {
                result.add(admission);
            }
        }

        // 第二轮：如果精确匹配结果较少，进行宽松匹配（学校UUID + 专业名称）
        if (result.size() < 3) { // 如果精确匹配结果少于3条，进行宽松匹配
            List<MajorAdmissionDO> looseMatches = findLooseMatches(allAdmissionData, major, profile);
            for (MajorAdmissionDO admission : looseMatches) {
                if (admission.getId() != null && addedIds.add(admission.getId())) {
                    result.add(admission);
                }
            }
        }

        log.debug("增强匹配完成 - 学校: {}, 专业: {}, 最终数据: {} 条",
                major.getSchoolUUID(), major.getMajorName(), result.size());

        return result;
    }

    /**
     * 精确匹配：学校UUID + 专业名称 + 类型匹配
     * 支持括号差异的专业名称匹配
     */
    private List<MajorAdmissionDO> findExactMatches(Map<String, List<MajorAdmissionDO>> allAdmissionData,
                                                   MajorAdmissionInfo major, UserProfileInfo profile) {
        List<MajorAdmissionDO> result = new ArrayList<>();

        for (Map.Entry<String, List<MajorAdmissionDO>> entry : allAdmissionData.entrySet()) {
            String key = entry.getKey();
            String[] keyParts = key.split(":");

            if (keyParts.length >= 5) {
                String schoolUuid = keyParts[0];
                String majorName = keyParts[1];
                String typeName = keyParts[4];

                // 使用增强的专业名称匹配，支持括号差异
                if (schoolUuid.equals(major.getSchoolUUID()) &&
                    isMajorNameMatch(majorName, major.getMajorName()) &&
                    (profile.getTypeName() == null || "null".equals(typeName) || typeName.equals(profile.getTypeName()))) {
                    result.addAll(entry.getValue());
                    log.debug("精确匹配成功 - 分组键专业: {}, 目标专业: {}, 分组键: {}",
                            majorName, major.getMajorName(), key);
                }
            }
        }

        return result;
    }

    /**
     * 宽松匹配：仅匹配学校UUID + 专业名称
     * 支持括号差异的专业名称匹配
     */
    private List<MajorAdmissionDO> findLooseMatches(Map<String, List<MajorAdmissionDO>> allAdmissionData,
                                                   MajorAdmissionInfo major, UserProfileInfo profile) {
        List<MajorAdmissionDO> result = new ArrayList<>();

        for (Map.Entry<String, List<MajorAdmissionDO>> entry : allAdmissionData.entrySet()) {
            String key = entry.getKey();
            String[] keyParts = key.split(":");

            if (keyParts.length >= 2) {
                String schoolUuid = keyParts[0];
                String majorName = keyParts[1];

                // 使用增强的专业名称匹配，支持括号差异
                if (schoolUuid.equals(major.getSchoolUUID()) && isMajorNameMatch(majorName, major.getMajorName())) {
                    result.addAll(entry.getValue());
                    log.debug("宽松匹配成功 - 分组键专业: {}, 目标专业: {}, 分组键: {}",
                            majorName, major.getMajorName(), key);
                }
            }
        }

        return result;
    }

    /**
     * 诊断数据匹配问题的方法
     * 用于分析为什么某些专业找不到匹配的录取数据
     *
     * @param allAdmissionData 所有录取数据的分组Map
     * @param major 专业信息
     * @param profile 用户信息
     */
    private void diagnoseMismatchedData(Map<String, List<MajorAdmissionDO>> allAdmissionData,
                                       MajorAdmissionInfo major, UserProfileInfo profile) {
        log.info("=== 开始诊断数据匹配问题 ===");
        log.info("目标专业 - 学校UUID: {}, 学校名称: {}, 专业名称: {}",
                major.getSchoolUUID(), major.getSchoolName(), major.getMajorName());
        log.info("用户信息 - 类型: {}, 省份: {}", profile.getTypeName(), profile.getProvince());

        // 统计分组键信息
        int totalGroups = allAdmissionData.size();
        int totalRecords = allAdmissionData.values().stream().mapToInt(List::size).sum();
        log.info("总分组数: {}, 总记录数: {}", totalGroups, totalRecords);

        // 查找相关的分组键
        List<String> relatedKeys = new ArrayList<>();
        List<String> schoolMatches = new ArrayList<>();
        List<String> majorMatches = new ArrayList<>();

        for (String key : allAdmissionData.keySet()) {
            String[] keyParts = key.split(":");
            if (keyParts.length >= 2) {
                String schoolUuid = keyParts[0];
                String majorName = keyParts[1];

                // 检查学校匹配
                if (schoolUuid.equals(major.getSchoolUUID())) {
                    schoolMatches.add(key);
                }

                // 检查专业匹配
                if (majorName.equals(major.getMajorName())) {
                    majorMatches.add(key);
                }

                // 检查完全匹配
                if (schoolUuid.equals(major.getSchoolUUID()) && majorName.equals(major.getMajorName())) {
                    relatedKeys.add(key);
                }
            }
        }

        log.info("学校UUID匹配的分组: {} 个", schoolMatches.size());
        log.info("专业名称匹配的分组: {} 个", majorMatches.size());
        log.info("学校+专业匹配的分组: {} 个", relatedKeys.size());

        // 详细分析匹配的分组键
        if (!relatedKeys.isEmpty()) {
            log.info("=== 匹配的分组键详情 ===");
            for (String key : relatedKeys) {
                String[] keyParts = key.split(":");
                List<MajorAdmissionDO> records = allAdmissionData.get(key);
                log.info("分组键: {} (记录数: {})", key, records.size());
                if (keyParts.length >= 6) {
                    log.info("  - 学校UUID: {}", keyParts[0]);
                    log.info("  - 专业名称: {}", keyParts[1]);
                    log.info("  - 年份: {}", keyParts[2]);
                    log.info("  - 批次: {}", keyParts[3]);
                    log.info("  - 类型: {}", keyParts[4]);
                    log.info("  - 选科组合: {}", keyParts[5]);
                }
            }
        } else {
            log.warn("未找到任何匹配的分组键！");

            // 显示一些示例分组键用于对比
            log.info("=== 示例分组键（前10个）===");
            allAdmissionData.keySet().stream().limit(10).forEach(key -> {
                log.info("示例分组键: {}", key);
            });
        }

        log.info("=== 诊断完成 ===");
    }

    /**
     * 构建查询信息说明（用于getAllSuitableMajors，包含分类信息）
     */
    private void buildQueryInfoForAllSuitableWithClassification(UserProfileInfo profile,
            List<MajorAdmissionInfo> rushMajors, List<MajorAdmissionInfo> stableMajors,
            List<MajorAdmissionInfo> safeMajors, StringBuilder queryInfo) {

        queryInfo.append("查询条件：\n");
        queryInfo.append("• 省份：").append(profile.getProvince()).append("\n");
        queryInfo.append("• 年份：").append(profile.getYear()).append("\n");
        queryInfo.append("• 选科：").append(String.join("、", profile.getSubjects())).append("\n");
        queryInfo.append("• 分数：").append(profile.getTotalScore()).append("分\n");

        // 显示实际使用的分数范围
        int actualMinScore = profile.getMinScore() != null ? profile.getMinScore() : profile.getTotalScore() - 100;
        int actualMaxScore = profile.getMaxScore() != null ? profile.getMaxScore() : profile.getTotalScore() + 50;
        queryInfo.append("• 分数范围：").append(actualMinScore).append("-").append(actualMaxScore).append("分");
        if (profile.getMinScore() != null || profile.getMaxScore() != null) {
            queryInfo.append("（用户自定义）");
        } else {
            queryInfo.append("（默认范围）");
        }
        queryInfo.append("\n");

        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            queryInfo.append("• 意向专业：").append(String.join("、", profile.getInterestedMajorCategories())).append("\n");
        }
        queryInfo.append("\n");

        queryInfo.append("查询结果（按冲稳保分类）：\n");
        queryInfo.append("• 冲刺专业：").append(rushMajors.size()).append("个（分数高于").append(profile.getTotalScore() + 10).append("分）\n");
        queryInfo.append("• 稳妥专业：").append(stableMajors.size()).append("个（分数在").append(profile.getTotalScore() - 10).append("-").append(profile.getTotalScore() + 10).append("分范围内）\n");
        queryInfo.append("• 保底专业：").append(safeMajors.size()).append("个（分数低于").append(profile.getTotalScore() - 10).append("分）\n");
        queryInfo.append("• 专业总数：").append(rushMajors.size() + stableMajors.size() + safeMajors.size()).append("个\n");

        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            queryInfo.append("• 所有专业均符合您的意向专业要求\n");
        }
        queryInfo.append("• 所有专业均符合您的选科要求\n");
        queryInfo.append("• 已过滤掉无招生计划的专业\n");
        queryInfo.append("• 已查询近三年（2022-2024）专业录取分数数据\n\n");

        // 分类分数范围统计
        if (!rushMajors.isEmpty()) {
            MajorAdmissionInfo rushLowest = rushMajors.get(0);
            MajorAdmissionInfo rushHighest = rushMajors.get(rushMajors.size() - 1);
            queryInfo.append("冲刺专业分数范围：").append(rushLowest.getLowestScore()).append("-").append(rushHighest.getLowestScore()).append("分\n");
        }

        if (!stableMajors.isEmpty()) {
            MajorAdmissionInfo stableLowest = stableMajors.get(0);
            MajorAdmissionInfo stableHighest = stableMajors.get(stableMajors.size() - 1);
            queryInfo.append("稳妥专业分数范围：").append(stableLowest.getLowestScore()).append("-").append(stableHighest.getLowestScore()).append("分\n");
        }

        if (!safeMajors.isEmpty()) {
            MajorAdmissionInfo safeLowest = safeMajors.get(0);
            MajorAdmissionInfo safeHighest = safeMajors.get(safeMajors.size() - 1);
            queryInfo.append("保底专业分数范围：").append(safeLowest.getLowestScore()).append("-").append(safeHighest.getLowestScore()).append("分\n");
        }
    }

    /**
     * 构建查询信息说明（用于getAllSuitableMajors）
     */
    private void buildQueryInfoForAllSuitable(UserProfileInfo profile, List<MajorAdmissionInfo> allSuitableMajors, StringBuilder queryInfo) {
        queryInfo.append("查询条件：\n");
        queryInfo.append("• 省份：").append(profile.getProvince()).append("\n");
        queryInfo.append("• 年份：").append(profile.getYear()).append("\n");
        queryInfo.append("• 选科：").append(String.join("、", profile.getSubjects())).append("\n");
        queryInfo.append("• 分数：").append(profile.getTotalScore()).append("分\n");

        // 显示实际使用的分数范围
        int actualMinScore = profile.getMinScore() != null ? profile.getMinScore() : profile.getTotalScore() - 100;
        int actualMaxScore = profile.getMaxScore() != null ? profile.getMaxScore() : profile.getTotalScore() + 50;
        queryInfo.append("• 分数范围：").append(actualMinScore).append("-").append(actualMaxScore).append("分");
        if (profile.getMinScore() != null || profile.getMaxScore() != null) {
            queryInfo.append("（用户自定义）");
        } else {
            queryInfo.append("（默认范围）");
        }
        queryInfo.append("\n");

        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            queryInfo.append("• 意向专业：").append(String.join("、", profile.getInterestedMajorCategories())).append("\n");
        }
        queryInfo.append("\n");

        queryInfo.append("查询结果：\n");
        queryInfo.append("• 共找到 ").append(allSuitableMajors.size()).append(" 个符合条件的专业\n");

        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            queryInfo.append("• 所有专业均符合您的意向专业要求\n");
        }
        queryInfo.append("• 所有专业均符合您的选科要求\n");
        queryInfo.append("• 专业按录取分数线从低到高排序\n");
        queryInfo.append("• 未进行招生计划筛选\n\n");

        if (!allSuitableMajors.isEmpty()) {
            MajorAdmissionInfo lowest = allSuitableMajors.get(0);
            MajorAdmissionInfo highest = allSuitableMajors.get(allSuitableMajors.size() - 1);
            queryInfo.append("分数范围：\n");
            queryInfo.append("• 最低分：").append(lowest.getLowestScore()).append("分（").append(lowest.getSchoolName()).append(" - ").append(lowest.getMajorName()).append("）\n");
            queryInfo.append("• 最高分：").append(highest.getLowestScore()).append("分（").append(highest.getSchoolName()).append(" - ").append(highest.getMajorName()).append("）\n");
        }
    }

    /**
     * 构建查询信息说明（原方法保留）
     */
    private void buildQueryInfo(UserProfileInfo profile, List<MajorAdmissionInfo> allSuitableMajors, StringBuilder queryInfo) {
        queryInfo.append("查询条件：\n");
        queryInfo.append("• 省份：").append(profile.getProvince()).append("\n");
        queryInfo.append("• 年份：").append(profile.getYear()).append("\n");
        queryInfo.append("• 选科：").append(String.join("、", profile.getSubjects())).append("\n");
        queryInfo.append("• 分数：").append(profile.getTotalScore()).append("分\n");

        // 显示实际使用的分数范围
        int actualMinScore = profile.getMinScore() != null ? profile.getMinScore() : profile.getTotalScore() - 100;
        int actualMaxScore = profile.getMaxScore() != null ? profile.getMaxScore() : profile.getTotalScore() + 50;
        queryInfo.append("• 分数范围：").append(actualMinScore).append("-").append(actualMaxScore).append("分");
        if (profile.getMinScore() != null || profile.getMaxScore() != null) {
            queryInfo.append("（用户自定义）");
        } else {
            queryInfo.append("（默认范围）");
        }
        queryInfo.append("\n\n");

        queryInfo.append("查询结果：\n");
        queryInfo.append("• 共找到 ").append(allSuitableMajors.size()).append(" 个符合条件的专业\n");
        queryInfo.append("• 所有专业均有招生计划数据\n");
        queryInfo.append("• 所有专业均符合您的选科要求\n");
        queryInfo.append("• 专业按录取分数线从低到高排序\n\n");

        if (!allSuitableMajors.isEmpty()) {
            MajorAdmissionInfo lowest = allSuitableMajors.get(0);
            MajorAdmissionInfo highest = allSuitableMajors.get(allSuitableMajors.size() - 1);
            queryInfo.append("分数范围：\n");
            queryInfo.append("• 最低分：").append(lowest.getLowestScore()).append("分（").append(lowest.getSchoolName()).append(" - ").append(lowest.getMajorName()).append("）\n");
            queryInfo.append("• 最高分：").append(highest.getLowestScore()).append("分（").append(highest.getSchoolName()).append(" - ").append(highest.getMajorName()).append("）\n");
        }
    }

    /**
     * 构建空的所有适合专业结果（冲稳保分类）
     */
    private Map<String, Object> buildEmptyAllSuitableResult(UserProfileInfo profile, StringBuilder queryInfo) {
        Map<String, Object> result = new HashMap<>();

        queryInfo.append("查询条件：\n");
        queryInfo.append("• 省份：").append(profile.getProvince()).append("\n");
        queryInfo.append("• 年份：").append(profile.getYear()).append("\n");
        queryInfo.append("• 选科：").append(String.join("、", profile.getSubjects())).append("\n");
        queryInfo.append("• 分数：").append(profile.getTotalScore()).append("分\n\n");

        queryInfo.append("查询结果：\n");
        queryInfo.append("• 未找到符合条件的专业\n");
        queryInfo.append("• 建议调整查询条件或联系客服获取帮助\n");

        result.put("rushMajors", new ArrayList<>());
        result.put("stableMajors", new ArrayList<>());
        result.put("safeMajors", new ArrayList<>());
        result.put("rushCount", 0);
        result.put("stableCount", 0);
        result.put("safeCount", 0);
        result.put("totalCount", 0);
        result.put("queryInfo", queryInfo.toString());
        return result;
    }

    /**
     * 构建错误的所有适合专业结果（冲稳保分类）
     */
    private Map<String, Object> buildErrorAllSuitableResult(String errorMessage) {
        Map<String, Object> result = new HashMap<>();
        result.put("rushMajors", new ArrayList<>());
        result.put("stableMajors", new ArrayList<>());
        result.put("safeMajors", new ArrayList<>());
        result.put("rushCount", 0);
        result.put("stableCount", 0);
        result.put("safeCount", 0);
        result.put("totalCount", 0);
        result.put("queryInfo", "查询过程中发生错误：" + errorMessage);
        return result;
    }

    /**
     * 根据直接参数获取所有适合的专业（兼容性方法，默认返回所有等级）
     * @param profile 用户个人信息
     * @return 所有适合的专业列表（按冲稳保分类）
     */
    public Map<String, Object> getAllSuitableMajorsByDirectParams(UserProfileInfo profile) {
        return getAllSuitableMajorsByDirectParams(profile, Arrays.asList("rush", "stable", "safe"));
    }

    /**
     * 根据直接参数获取所有适合的专业（彻底重构版本）
     * 数据处理步骤：
     * 1. 先读招生计划表筛选出符合条件的数据
     * 2. 再根据条件读专业录取分数线表
     * 3. 再分组
     * @param profile 用户个人信息
     * @param levelTypes 要返回的等级类型列表，为空时默认只返回冲刺等级
     * @return 所有适合的专业列表（按冲稳保分类）
     */
    public Map<String, Object> getAllSuitableMajorsByDirectParams(UserProfileInfo profile, List<String> levelTypes) {
        long startTime = System.currentTimeMillis();

        // 处理 levelTypes 参数，默认返回所有等级
        Set<String> requestedLevels = new HashSet<>();
        if (levelTypes == null || levelTypes.isEmpty()) {
            requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            log.info("未指定等级类型，默认返回所有等级数据");
        } else {
            requestedLevels.addAll(levelTypes);
            log.info("用户请求的等级类型：{}", requestedLevels);
        }

        log.info("开始获取所有适合专业（重构版本），用户省份：{}，分数：{}，选科：{}，意向专业：{}，请求等级：{}",
                profile.getProvince(), profile.getTotalScore(), profile.getSubjects(), profile.getInterestedMajorCategories(), requestedLevels);

        Map<String, Object> result = new HashMap<>();
        StringBuilder queryInfo = new StringBuilder();
        List<MajorAdmissionInfo> rushMajors = new ArrayList<>();
        List<MajorAdmissionInfo> stableMajors = new ArrayList<>();
        List<MajorAdmissionInfo> safeMajors = new ArrayList<>();

        try {
            // 第一步：从招生计划表筛选符合条件的学校专业组合
            List<CollegeEnrollmentPlanDO> enrollmentPlans = filterEnrollmentPlansByConditions(profile);
            log.info("第一步：从招生计划表筛选得到 {} 条符合条件的学校专业组合", enrollmentPlans.size());

            if (enrollmentPlans.isEmpty()) {
                return buildEmptyDirectParamsResult(profile, queryInfo);
            }

            // 第二步：根据招生计划结果查询专业录取分数线表
            List<MajorAdmissionInfo> admissionInfos = queryAdmissionScoresByEnrollmentPlans(enrollmentPlans, profile);
            log.info("第二步：根据招生计划查询专业录取分数线得到 {} 条数据", admissionInfos.size());

            if (admissionInfos.isEmpty()) {
                return buildEmptyDirectParamsResult(profile, queryInfo);
            }

            // 第三步：按冲稳保分组
            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByScore(admissionInfos, profile.getTotalScore());

            rushMajors = classifiedMajors.get("rush");
            stableMajors = classifiedMajors.get("stable");
            safeMajors = classifiedMajors.get("safe");

            log.info("第三步：专业分组完成 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                    rushMajors.size(), stableMajors.size(), safeMajors.size());

            // 第四步：为请求的等级查询近三年数据
            if (requestedLevels.contains("rush") && !rushMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(rushMajors, profile);
                log.info("为冲刺等级查询近三年数据完成");
            }
            if (requestedLevels.contains("stable") && !stableMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(stableMajors, profile);
                log.info("为稳妥等级查询近三年数据完成");
            }
            if (requestedLevels.contains("safe") && !safeMajors.isEmpty()) {
                batchQueryThreeYearsAdmissionScores(safeMajors, profile);
                log.info("为保底等级查询近三年数据完成");
            }

            // 构建查询信息
            buildDirectParamsQueryInfo(profile, queryInfo, rushMajors.size(), stableMajors.size(), safeMajors.size());

        } catch (Exception e) {
            log.error("获取所有适合专业时发生错误（重构版本）", e);
            return buildEmptyDirectParamsResult(profile, queryInfo);
        }

        // 构建返回结果，根据请求的等级过滤数据
        result.put("rushMajors", requestedLevels.contains("rush") ? rushMajors : new ArrayList<>());
        result.put("stableMajors", requestedLevels.contains("stable") ? stableMajors : new ArrayList<>());
        result.put("safeMajors", requestedLevels.contains("safe") ? safeMajors : new ArrayList<>());
        result.put("rushCount", requestedLevels.contains("rush") ? rushMajors.size() : 0);
        result.put("stableCount", requestedLevels.contains("stable") ? stableMajors.size() : 0);
        result.put("safeCount", requestedLevels.contains("safe") ? safeMajors.size() : 0);

        int totalCount = 0;
        if (requestedLevels.contains("rush")) {
            totalCount += rushMajors.size();
        }
        if (requestedLevels.contains("stable")) {
            totalCount += stableMajors.size();
        }
        if (requestedLevels.contains("safe")) {
            totalCount += safeMajors.size();
        }

        result.put("totalCount", totalCount);
        result.put("queryInfo", queryInfo.toString());
        result.put("requestedLevels", new ArrayList<>(requestedLevels)); // 返回请求的等级信息

        long endTime = System.currentTimeMillis();
        log.info("获取所有适合专业完成（直接参数版本），总耗时: {}ms，总专业数: {}",
                endTime - startTime, rushMajors.size() + stableMajors.size() + safeMajors.size());

        return result;
    }

    /**
     * 分页版本：根据用户个人信息获取所有适合的专业（重构版本）
     * 数据处理步骤：
     * 1. 先读招生计划表筛选出符合条件的数据
     * 2. 再根据条件读专业录取分数线表
     * 3. 再分组
     * @param profile 用户个人信息
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param majorType 专业类型过滤 (rush/stable/safe)
     * @return 分页的专业列表和统计信息
     */
    public Map<String, Object> getAllSuitableMajorsWithPagination(UserProfileInfo profile, Integer pageNo, Integer pageSize, String majorType) {
        long startTime = System.currentTimeMillis();
        log.info("开始分页获取所有适合专业（重构版本），用户省份：{}，分数：{}，页码：{}，每页大小：{}，专业类型：{}",
                profile.getProvince(), profile.getTotalScore(), pageNo, pageSize, majorType);

        Map<String, Object> result = new HashMap<>();
        StringBuilder queryInfo = new StringBuilder();

        try {
            // 首先获取完整的专业数据（不分页）
            Map<String, Object> fullResult = getAllSuitableMajors(profile);

            // 提取各类专业数据
            List<MajorAdmissionInfo> rushMajors = (List<MajorAdmissionInfo>) fullResult.get("rushMajors");
            List<MajorAdmissionInfo> stableMajors = (List<MajorAdmissionInfo>) fullResult.get("stableMajors");
            List<MajorAdmissionInfo> safeMajors = (List<MajorAdmissionInfo>) fullResult.get("safeMajors");

            // 根据majorType选择要分页的专业列表
            List<MajorAdmissionInfo> targetMajors;
            String currentMajorType;

            if ("rush".equals(majorType)) {
                targetMajors = rushMajors;
                currentMajorType = "rush";
            } else if ("stable".equals(majorType)) {
                targetMajors = stableMajors;
                currentMajorType = "stable";
            } else if ("safe".equals(majorType)) {
                targetMajors = safeMajors;
                currentMajorType = "safe";
            } else {
                // 默认返回冲刺专业
                targetMajors = rushMajors;
                currentMajorType = "rush";
            }

            // 执行分页
            int total = targetMajors.size();
            int startIndex = (pageNo - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, total);

            List<MajorAdmissionInfo> pagedMajors;
            if (startIndex >= total) {
                pagedMajors = new ArrayList<>();
            } else {
                pagedMajors = targetMajors.subList(startIndex, endIndex);
            }

            // 构建分页结果
            result.put("majors", pagedMajors);
            result.put("rushCount", rushMajors.size());
            result.put("stableCount", stableMajors.size());
            result.put("safeCount", safeMajors.size());
            result.put("totalCount", rushMajors.size() + stableMajors.size() + safeMajors.size());
            result.put("currentMajorType", currentMajorType);
            result.put("currentTypeTotal", total);
            result.put("queryInfo", fullResult.get("queryInfo"));

            long endTime = System.currentTimeMillis();
            log.info("分页获取所有适合专业完成，耗时：{}ms，类型：{}，总数：{}，返回：{}个",
                    endTime - startTime, currentMajorType, total, pagedMajors.size());

        } catch (Exception e) {
            log.error("分页获取所有适合专业过程中发生异常", e);
            return buildErrorAllSuitablePageResult(e.getMessage());
        }

        return result;
    }

    /**
     * 构建错误的分页专业结果
     */
    private Map<String, Object> buildErrorAllSuitablePageResult(String errorMessage) {
        Map<String, Object> result = new HashMap<>();
        result.put("majors", new ArrayList<>());
        result.put("rushCount", 0);
        result.put("stableCount", 0);
        result.put("safeCount", 0);
        result.put("totalCount", 0);
        result.put("currentMajorType", "rush");
        result.put("currentTypeTotal", 0);
        result.put("queryInfo", "查询过程中发生错误：" + errorMessage);
        return result;
    }

    // ==================== 直接参数版本的辅助方法 ====================

    /**
     * 优化版本：一次性查询候选专业数据（重构版本：先读招生计划表）
     * @deprecated 使用 filterEnrollmentPlansByConditions + queryAdmissionScoresByEnrollmentPlans 替代
     */
    @Deprecated
    private List<MajorAdmissionInfo> queryDirectParamsCandidateMajorsOptimized(UserProfileInfo profile) {
        log.warn("使用了已废弃的 queryDirectParamsCandidateMajorsOptimized 方法，建议使用新的重构方法");

        // 使用新的重构流程
        List<CollegeEnrollmentPlanDO> enrollmentPlans = filterEnrollmentPlansByConditions(profile);
        return queryAdmissionScoresByEnrollmentPlans(enrollmentPlans, profile);
    }

    /**
     * 查询直接参数版本的候选专业数据（含兴趣匹配）
     * @deprecated 使用 queryDirectParamsCandidateMajorsOptimized 替代
     */
    @Deprecated
    private List<MajorAdmissionInfo> queryDirectParamsCandidateMajors(UserProfileInfo profile) {
        // 使用用户设置的分数范围，如果没有设置则使用默认值
        int minScore;
        int maxScore;

        if (profile.getMinScore() != null) {
            minScore = profile.getMinScore();
            log.info("使用用户自定义最低分数: {}", minScore);
        } else {
            minScore = profile.getTotalScore() - 60; // 默认范围：用户分数减60
            log.info("使用默认最低分数: {} (用户分数-60)", minScore);
        }

        if (profile.getMaxScore() != null) {
            maxScore = profile.getMaxScore();
            log.info("使用用户自定义最高分数: {}", maxScore);
        } else {
            maxScore = profile.getTotalScore() + 30; // 默认范围：用户分数加30
            log.info("使用默认最高分数: {} (用户分数+30)", maxScore);
        }

        String provinceName = profile.getProvince();
        Integer year = profile.getYear() != null ? profile.getYear() : 2024;

        log.info("查询参数 - 省份: {}, 年份: {}, 分数范围: {}-{}", provinceName, year, minScore, maxScore);

        List<MajorAdmissionInfo> allCandidateMajors = new ArrayList<>();

        // 如果用户有意向专业，进行兴趣匹配查询
        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            log.info("用户有意向专业，进行兴趣匹配查询: {}", profile.getInterestedMajorCategories());

            Set<String> uniqueMajorKeys = new HashSet<>();

            for (String category : profile.getInterestedMajorCategories()) {
                List<String> keywords = splitMajorNameToKeywords(category);
                log.info("专业类别 '{}' 分解为关键词: {}", category, keywords);

                for (String keyword : keywords) {
                    try {
                        List<MajorAdmissionDO> results = majorAdmissionMapper
                                .selectByProvinceYearScoreRangeAndMajorKeywords(provinceName, year, minScore, maxScore, keyword);

                        log.info("关键词 '{}' 查询到 {} 条数据", keyword, results.size());

                        for (MajorAdmissionDO admission : results) {
                            String uniqueKey = admission.getSchoolName() + ":" + admission.getMajorName();
                            if (!uniqueMajorKeys.contains(uniqueKey)) {
                                uniqueMajorKeys.add(uniqueKey);
                                MajorAdmissionInfo info = convertToMajorAdmissionInfo(admission);
                                allCandidateMajors.add(info);
                            }
                        }
                    } catch (Exception e) {
                        log.error("查询关键词 '{}' 时发生错误", keyword, e);
                    }
                }
            }

            log.info("兴趣匹配查询完成，去重后得到 {} 条专业数据", allCandidateMajors.size());
        } else {
            // 如果没有意向专业，查询所有符合分数范围的专业
            log.info("用户未指定意向专业，查询所有符合分数范围的专业");
            try {
                List<MajorAdmissionDO> results = majorAdmissionMapper
                        .selectByProvinceYearAndScoreRange(provinceName, year, minScore, maxScore);

                log.info("查询到 {} 条符合分数范围的专业数据", results.size());

                for (MajorAdmissionDO admission : results) {
                    MajorAdmissionInfo info = convertToMajorAdmissionInfo(admission);
                    allCandidateMajors.add(info);
                }
            } catch (Exception e) {
                log.error("查询所有符合分数范围的专业时发生错误", e);
            }
        }

        log.info("直接参数版本候选专业查询完成，共 {} 条数据", allCandidateMajors.size());
        return allCandidateMajors;
    }

    /**
     * 第一步：从专业录取分数线中获取对应的数据
     * 根据省份、年份、分数范围、意向专业等条件查询专业录取数据
     * @param profile 用户个人信息
     * @return 专业录取信息列表
     */
    private List<MajorAdmissionInfo> queryMajorAdmissionDataByConditions(UserProfileInfo profile) {
        String provinceName = profile.getProvince();
        Integer year = 2024;
        String typeName = profile.getTypeName();
        List<String> interestedMajors = profile.getInterestedMajorCategories();

        // 计算分数范围
        int minScore = profile.getMinScore() != null ? profile.getMinScore() : profile.getTotalScore() - 60;
        int maxScore = profile.getMaxScore() != null ? profile.getMaxScore() : profile.getTotalScore() + 30;

        log.info("开始从专业录取分数线查询数据 - 省份: {}, 年份: {}, 类型: {}, 分数范围: {}-{}, 意向专业: {}",
                provinceName, year, typeName, minScore, maxScore, interestedMajors);

        List<MajorAdmissionInfo> allCandidateMajors = new ArrayList<>();

        try {
            if (interestedMajors != null && !interestedMajors.isEmpty()) {
                // 如果有意向专业，按关键词查询
                log.info("用户指定了意向专业，按关键词查询：{}", interestedMajors);

                for (String majorCategory : interestedMajors) {
                    List<String> keywords = splitMajorNameToKeywords(majorCategory);
                    for (String keyword : keywords) {
                        if (keyword.length() >= 2) { // 只处理长度>=2的关键词
                            List<MajorAdmissionDO> results = queryByKeywordInDatabase(provinceName, year, minScore, maxScore, typeName, keyword);
                            for (MajorAdmissionDO admission : results) {
                                MajorAdmissionInfo info = convertToMajorAdmissionInfo(admission);
                                allCandidateMajors.add(info);
                            }
                        }
                    }
                }

                // 去重处理
                allCandidateMajors = deduplicateMajorAdmissionInfos(allCandidateMajors);
                log.info("意向专业匹配查询完成，去重后得到 {} 条专业数据", allCandidateMajors.size());
            } else {
                // 如果没有意向专业，查询所有符合分数范围的专业
                log.info("用户未指定意向专业，查询所有符合分数范围的专业");
                List<MajorAdmissionDO> results = getAdmissionDataByProvinceYearTypeAndScore(provinceName, year, typeName, minScore, maxScore);

                for (MajorAdmissionDO admission : results) {
                    MajorAdmissionInfo info = convertToMajorAdmissionInfo(admission);
                    allCandidateMajors.add(info);
                }
                log.info("查询到 {} 条符合分数范围的专业数据", allCandidateMajors.size());
            }

            return allCandidateMajors;

        } catch (Exception e) {
            log.error("从专业录取分数线查询数据时发生错误", e);
            return new ArrayList<>();
        }
    }

    /**
     * 第一步：从招生计划表筛选符合条件的学校专业组合
     * 根据省份、年份、选科要求、期望学校所在地等条件筛选招生计划
     * @param profile 用户个人信息
     * @return 符合条件的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansByConditions(UserProfileInfo profile) {
        String provinceName = profile.getProvince();
        Integer year = profile.getYear() != null ? profile.getYear() : 2024;
        List<String> subjects = profile.getSubjects();
        List<String> interestedMajors = profile.getInterestedMajorCategories();
        String preferredLocation = profile.getPreferredLocation();
        String batchName = profile.getBatchName();
        String typeName = profile.getTypeName();
        String schoolName = profile.getSchoolName();
        List<String> schoolFeatures = profile.getSchoolFeatures();
        List<String> schoolNature = profile.getSchoolProperties();
        List<String> universityTypes = profile.getSchoolTypes();

        log.info("开始从招生计划表筛选数据 - 省份: {}, 年份: {}, 选科: {}, 意向专业: {}, 期望学校所在地: {}, 录取批次: {}, 学校名称: {}, 院校特色: {}, 办学性质: {}, 大学类型: {}",
                provinceName, year, subjects, interestedMajors, preferredLocation, batchName, schoolName, schoolFeatures, schoolNature, universityTypes);

        try {
            // 基础查询条件：省份和年份
            List<CollegeEnrollmentPlanDO> enrollmentPlans = collegeEnrollmentPlanMapper
                    .selectListByProvinceAndYearAndType(provinceName, year,typeName);

            log.info("基础查询（省份+年份）得到 {} 条招生计划数据", enrollmentPlans.size());

            if (enrollmentPlans.isEmpty()) {
                return enrollmentPlans;
            }

            // 过滤选科要求
            if (subjects != null && !subjects.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansBySubjects(enrollmentPlans, subjects);
                log.info("选科筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤意向专业
            if (interestedMajors != null && !interestedMajors.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansByInterestedMajors(enrollmentPlans, interestedMajors);
                log.info("意向专业筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤期望学校所在地
            if (preferredLocation != null && !preferredLocation.trim().isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansByPreferredLocation(enrollmentPlans, preferredLocation);
                log.info("期望学校所在地筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤录取批次
            if (batchName != null && !batchName.trim().isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansByBatchName(enrollmentPlans, batchName);
                log.info("录取批次筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤学校名称
            if (schoolName != null && !schoolName.trim().isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansBySchoolName(enrollmentPlans, schoolName);
                log.info("学校名称筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤院校特色
            if (schoolFeatures != null && !schoolFeatures.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansBySchoolFeatures(enrollmentPlans, schoolFeatures);
                log.info("院校特色筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤办学性质
            if (schoolNature != null && !schoolNature.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansBySchoolNature(enrollmentPlans, schoolNature);
                log.info("办学性质筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤大学类型
            if (universityTypes != null && !universityTypes.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansByUniversityTypes(enrollmentPlans, universityTypes);
                log.info("大学类型筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            return enrollmentPlans;

        } catch (Exception e) {
            log.error("从招生计划表筛选数据时发生错误", e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据选科要求过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param userSubjects 用户选科
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansBySubjects(List<CollegeEnrollmentPlanDO> enrollmentPlans, List<String> userSubjects) {
        if (userSubjects == null || userSubjects.isEmpty()) {
            return enrollmentPlans;
        }

        List<CollegeEnrollmentPlanDO> filteredPlans = new ArrayList<>();

        for (CollegeEnrollmentPlanDO plan : enrollmentPlans) {
            String courseSelectionRequirements = plan.getCourseSelectionRequirements();

            // 如果没有选科要求，则认为符合条件
            if (courseSelectionRequirements == null || courseSelectionRequirements.trim().isEmpty()
                    || "不限".equals(courseSelectionRequirements) || "无".equals(courseSelectionRequirements)) {
                filteredPlans.add(plan);
                continue;
            }

            // 检查用户选科是否满足要求
            Set<String> userSubjectsSet = new HashSet<>(userSubjects);
            if (checkSubjectRequirements(userSubjectsSet, courseSelectionRequirements)) {
                filteredPlans.add(plan);
            }
        }

        return filteredPlans;
    }

    /**
     * 根据意向专业过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param interestedMajors 意向专业列表
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansByInterestedMajors(List<CollegeEnrollmentPlanDO> enrollmentPlans, List<String> interestedMajors) {
        if (interestedMajors == null || interestedMajors.isEmpty()) {
            return enrollmentPlans;
        }

        List<CollegeEnrollmentPlanDO> filteredPlans = new ArrayList<>();

        // 将意向专业转换为关键词集合
        Set<String> allKeywords = new HashSet<>();
        for (String major : interestedMajors) {
            List<String> keywords = splitMajorNameToKeywords(major);
            allKeywords.addAll(keywords);
        }

        log.info("意向专业关键词: {}", allKeywords);

        for (CollegeEnrollmentPlanDO plan : enrollmentPlans) {
            String majorName = plan.getCollegeMajorName();

            if (majorName == null || majorName.trim().isEmpty()) {
                continue;
            }

            // 检查专业名称是否匹配任何关键词
            boolean matched = false;
            for (String keyword : allKeywords) {
                if (keyword.length() >= 2 && majorName.contains(keyword)) {
                    matched = true;
                    break;
                }
            }

            if (matched) {
                filteredPlans.add(plan);
            }
        }

        return filteredPlans;
    }

    /**
     * 根据期望学校所在地过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param preferredLocation 期望学校所在地
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansByPreferredLocation(List<CollegeEnrollmentPlanDO> enrollmentPlans, String preferredLocation) {
        if (preferredLocation == null || preferredLocation.trim().isEmpty()) {
            return enrollmentPlans;
        }

        log.info("开始按期望学校所在地筛选，期望所在地: {}", preferredLocation);

        try {
            // 提取所有学校UUID
            List<String> schoolUuids = enrollmentPlans.stream()
                    .map(CollegeEnrollmentPlanDO::getSchoolUuid)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (schoolUuids.isEmpty()) {
                log.warn("招生计划中没有有效的学校UUID");
                return enrollmentPlans;
            }

            log.info("需要查询学校信息的UUID数量: {}", schoolUuids.size());

            // 查询学校信息，筛选出符合所在地要求的学校
            List<CollegeDO> colleges = collegeMapper.selectBySchoolUuids(schoolUuids);
            log.info("查询到 {} 条学校信息", colleges.size());

            // 筛选符合所在地要求的学校UUID
            Set<String> validSchoolUuids = new HashSet<>();
            for (CollegeDO college : colleges) {
                if (isLocationMatch(college, preferredLocation)) {
                    validSchoolUuids.add(college.getSchoolUuid());
                }
            }

            log.info("符合期望所在地 '{}' 的学校数量: {}", preferredLocation, validSchoolUuids.size());

            if (validSchoolUuids.isEmpty()) {
                log.warn("没有找到符合期望所在地的学校");
                return new ArrayList<>();
            }

            // 过滤招生计划，只保留符合所在地要求的学校
            List<CollegeEnrollmentPlanDO> filteredPlans = enrollmentPlans.stream()
                    .filter(plan -> validSchoolUuids.contains(plan.getSchoolUuid()))
                    .collect(Collectors.toList());

            log.info("按期望学校所在地筛选完成，原始数量: {}, 过滤后数量: {}", enrollmentPlans.size(), filteredPlans.size());
            return filteredPlans;

        } catch (Exception e) {
            log.error("按期望学校所在地筛选时发生错误", e);
            return enrollmentPlans; // 发生错误时返回原始数据
        }
    }

    /**
     * 检查学校所在地是否匹配用户期望
     * @param college 学校信息
     * @param preferredLocation 期望所在地
     * @return 是否匹配
     */
    private boolean isLocationMatch(CollegeDO college, String preferredLocation) {
        if (college == null || preferredLocation == null) {
            return false;
        }

        String trimmedLocation = preferredLocation.trim();

        // 检查省份匹配
        if (college.getProvince() != null && college.getProvince().contains(trimmedLocation)) {
            return true;
        }

        // 检查城市匹配
        if (college.getCity() != null && college.getCity().contains(trimmedLocation)) {
            return true;
        }

        // 检查区县匹配
        if (college.getDistrict() != null && college.getDistrict().contains(trimmedLocation)) {
            return true;
        }

        // 反向检查：期望所在地包含学校的省份或城市
        if (college.getProvince() != null && trimmedLocation.contains(college.getProvince())) {
            return true;
        }

        if (college.getCity() != null && trimmedLocation.contains(college.getCity())) {
            return true;
        }

        return false;
    }

    /**
     * 根据录取批次过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param batchName 录取批次
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansByBatchName(List<CollegeEnrollmentPlanDO> enrollmentPlans, String batchName) {
        if (batchName == null || batchName.trim().isEmpty()) {
            return enrollmentPlans;
        }

        log.info("开始按录取批次筛选，录取批次: {}", batchName);

        try {
            String trimmedBatchName = batchName.trim();

            // 过滤招生计划，只保留符合批次要求的数据
            List<CollegeEnrollmentPlanDO> filteredPlans = enrollmentPlans.stream()
                    .filter(plan -> isBatchNameMatch(plan.getBatchName(), trimmedBatchName))
                    .collect(Collectors.toList());

            log.info("按录取批次筛选完成，原始数量: {}, 过滤后数量: {}", enrollmentPlans.size(), filteredPlans.size());
            return filteredPlans;

        } catch (Exception e) {
            log.error("按录取批次筛选时发生错误", e);
            return enrollmentPlans; // 发生错误时返回原始数据
        }
    }

    /**
     * 检查批次名称是否匹配
     * @param planBatchName 招生计划中的批次名称
     * @param targetBatchName 目标批次名称
     * @return 是否匹配
     */
    private boolean isBatchNameMatch(String planBatchName, String targetBatchName) {
        if (planBatchName == null || targetBatchName == null) {
            return false;
        }

        String trimmedPlanBatch = planBatchName.trim();
        String trimmedTargetBatch = targetBatchName.trim();

        // 精确匹配
        if (trimmedPlanBatch.equals(trimmedTargetBatch)) {
            return true;
        }

        // 包含匹配（双向）
        if (trimmedPlanBatch.contains(trimmedTargetBatch) || trimmedTargetBatch.contains(trimmedPlanBatch)) {
            return true;
        }

        return false;
    }

    /**
     * 根据学校名称过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param schoolName 学校名称（支持模糊搜索）
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansBySchoolName(List<CollegeEnrollmentPlanDO> enrollmentPlans, String schoolName) {
        if (schoolName == null || schoolName.trim().isEmpty()) {
            return enrollmentPlans;
        }

        log.info("开始按学校名称筛选，学校名称: {}", schoolName);

        try {
            String trimmedSchoolName = schoolName.trim();

            // 过滤招生计划，只保留学校名称匹配的数据
            List<CollegeEnrollmentPlanDO> filteredPlans = enrollmentPlans.stream()
                    .filter(plan -> isSchoolNameMatch(plan.getSchoolName(), trimmedSchoolName))
                    .collect(Collectors.toList());

            log.info("按学校名称筛选完成，原始数量: {}, 过滤后数量: {}", enrollmentPlans.size(), filteredPlans.size());
            return filteredPlans;

        } catch (Exception e) {
            log.error("按学校名称筛选时发生错误", e);
            return enrollmentPlans; // 发生错误时返回原始数据
        }
    }

    /**
     * 检查学校名称是否匹配
     * @param planSchoolName 招生计划中的学校名称
     * @param targetSchoolName 目标学校名称
     * @return 是否匹配
     */
    private boolean isSchoolNameMatch(String planSchoolName, String targetSchoolName) {
        if (planSchoolName == null || targetSchoolName == null) {
            return false;
        }

        String trimmedPlanSchool = planSchoolName.trim();
        String trimmedTargetSchool = targetSchoolName.trim();

        // 精确匹配
        if (trimmedPlanSchool.equals(trimmedTargetSchool)) {
            return true;
        }

        // 包含匹配（双向）
        if (trimmedPlanSchool.contains(trimmedTargetSchool) || trimmedTargetSchool.contains(trimmedPlanSchool)) {
            return true;
        }

        return false;
    }

    /**
     * 根据院校特色过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param schoolFeatures 院校特色列表
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansBySchoolFeatures(List<CollegeEnrollmentPlanDO> enrollmentPlans, List<String> schoolFeatures) {
        if (schoolFeatures == null || schoolFeatures.isEmpty()) {
            return enrollmentPlans;
        }

        log.info("开始按院校特色筛选，院校特色: {}", schoolFeatures);

        try {
            // 提取所有学校UUID
            List<String> schoolUuids = enrollmentPlans.stream()
                    .map(CollegeEnrollmentPlanDO::getSchoolUuid)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (schoolUuids.isEmpty()) {
                log.warn("招生计划中没有有效的学校UUID");
                return enrollmentPlans;
            }

            log.info("需要查询学校信息的UUID数量: {}", schoolUuids.size());

            // 查询学校信息，筛选出符合院校特色要求的学校
            List<CollegeDO> colleges = collegeMapper.selectBySchoolUuids(schoolUuids);
            log.info("查询到 {} 条学校信息", colleges.size());

            // 筛选符合院校特色要求的学校UUID
            Set<String> validSchoolUuids = new HashSet<>();
            for (CollegeDO college : colleges) {
                if (isSchoolFeaturesMatch(college, schoolFeatures)) {
                    validSchoolUuids.add(college.getSchoolUuid());
                }
            }

            log.info("符合院校特色 '{}' 的学校数量: {}", schoolFeatures, validSchoolUuids.size());

            if (validSchoolUuids.isEmpty()) {
                log.warn("没有找到符合院校特色的学校");
                return new ArrayList<>();
            }

            // 过滤招生计划，只保留符合院校特色要求的学校
            List<CollegeEnrollmentPlanDO> filteredPlans = enrollmentPlans.stream()
                    .filter(plan -> validSchoolUuids.contains(plan.getSchoolUuid()))
                    .collect(Collectors.toList());

            log.info("按院校特色筛选完成，原始数量: {}, 过滤后数量: {}", enrollmentPlans.size(), filteredPlans.size());
            return filteredPlans;

        } catch (Exception e) {
            log.error("按院校特色筛选时发生错误", e);
            return enrollmentPlans; // 发生错误时返回原始数据
        }
    }

    /**
     * 检查学校是否符合院校特色要求
     * @param college 学校信息
     * @param schoolFeatures 院校特色列表
     * @return 是否匹配
     */
    private boolean isSchoolFeaturesMatch(CollegeDO college, List<String> schoolFeatures) {
        if (college == null || schoolFeatures == null || schoolFeatures.isEmpty()) {
            return false;
        }

        for (String feature : schoolFeatures) {
            switch (feature) {
                case "985":
                    if (college.getIs985() != null && college.getIs985()) {
                        return true;
                    }
                    break;
                case "211":
                    if (college.getIs211() != null && college.getIs211()) {
                        return true;
                    }
                    break;
                case "双一流":
                    if (college.getIsDualClass() != null && college.getIsDualClass()) {
                        return true;
                    }
                    break;
                case "教育部直属":
                    if (college.getCollegeProperty() != null && college.getCollegeProperty().contains("教育部直属")) {
                        return true;
                    }
                    break;
                case "中央部委":
                    if (college.getCollegeProperty() != null && college.getCollegeProperty().contains("中央部委")) {
                        return true;
                    }
                    break;
                case "强基计划":
                    if (college.getCollegeTags() != null && college.getCollegeTags().contains("强基计划")) {
                        return true;
                    }
                    break;
            }
        }

        return false;
    }

    /**
     * 根据办学性质过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param schoolNature 办学性质列表
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansBySchoolNature(List<CollegeEnrollmentPlanDO> enrollmentPlans, List<String> schoolNature) {
        if (schoolNature == null || schoolNature.isEmpty()) {
            return enrollmentPlans;
        }

        log.info("开始按办学性质筛选，办学性质: {}", schoolNature);

        try {
            // 提取所有学校UUID
            List<String> schoolUuids = enrollmentPlans.stream()
                    .map(CollegeEnrollmentPlanDO::getSchoolUuid)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (schoolUuids.isEmpty()) {
                log.warn("招生计划中没有有效的学校UUID");
                return enrollmentPlans;
            }

            // 查询学校信息，筛选出符合办学性质要求的学校
            List<CollegeDO> colleges = collegeMapper.selectBySchoolUuids(schoolUuids);
            log.info("查询到 {} 条学校信息", colleges.size());

            // 筛选符合办学性质要求的学校UUID
            Set<String> validSchoolUuids = new HashSet<>();
            for (CollegeDO college : colleges) {
                if (isSchoolNatureMatch(college, schoolNature)) {
                    validSchoolUuids.add(college.getSchoolUuid());
                }
            }

            log.info("符合办学性质 '{}' 的学校数量: {}", schoolNature, validSchoolUuids.size());

            if (validSchoolUuids.isEmpty()) {
                log.warn("没有找到符合办学性质的学校");
                return new ArrayList<>();
            }

            // 过滤招生计划，只保留符合办学性质要求的学校
            List<CollegeEnrollmentPlanDO> filteredPlans = enrollmentPlans.stream()
                    .filter(plan -> validSchoolUuids.contains(plan.getSchoolUuid()))
                    .collect(Collectors.toList());

            log.info("按办学性质筛选完成，原始数量: {}, 过滤后数量: {}", enrollmentPlans.size(), filteredPlans.size());
            return filteredPlans;

        } catch (Exception e) {
            log.error("按办学性质筛选时发生错误", e);
            return enrollmentPlans; // 发生错误时返回原始数据
        }
    }

    /**
     * 检查学校是否符合办学性质要求
     * @param college 学校信息
     * @param schoolNature 办学性质列表
     * @return 是否匹配
     */
    private boolean isSchoolNatureMatch(CollegeDO college, List<String> schoolNature) {
        if (college == null || schoolNature == null || schoolNature.isEmpty()) {
            return false;
        }

        String collegeType = college.getCollegeType();
        String collegeProperty = college.getCollegeProperty();

        for (String nature : schoolNature) {
            switch (nature) {
                case "公办":
                    if ((collegeType != null && collegeType.contains("公办")) ||
                        (collegeProperty != null && collegeProperty.contains("公办"))) {
                        return true;
                    }
                    break;
                case "民办":
                    if ((collegeType != null && collegeType.contains("民办")) ||
                        (collegeProperty != null && collegeProperty.contains("民办"))) {
                        return true;
                    }
                    break;
                case "中外合作":
                    if ((collegeType != null && collegeType.contains("中外合作")) ||
                        (collegeProperty != null && collegeProperty.contains("中外合作"))) {
                        return true;
                    }
                    break;
                case "内地与港澳台地区合作办学":
                    if ((collegeType != null && collegeType.contains("港澳台")) ||
                        (collegeProperty != null && collegeProperty.contains("港澳台"))) {
                        return true;
                    }
                    break;
            }
        }

        return false;
    }

    /**
     * 根据大学类型过滤招生计划
     * @param enrollmentPlans 招生计划列表
     * @param universityTypes 大学类型列表
     * @return 过滤后的招生计划列表
     */
    private List<CollegeEnrollmentPlanDO> filterEnrollmentPlansByUniversityTypes(List<CollegeEnrollmentPlanDO> enrollmentPlans, List<String> universityTypes) {
        if (universityTypes == null || universityTypes.isEmpty()) {
            return enrollmentPlans;
        }

        log.info("开始按大学类型筛选，大学类型: {}", universityTypes);

        try {
            // 提取所有学校UUID
            List<String> schoolUuids = enrollmentPlans.stream()
                    .map(CollegeEnrollmentPlanDO::getSchoolUuid)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (schoolUuids.isEmpty()) {
                log.warn("招生计划中没有有效的学校UUID");
                return enrollmentPlans;
            }

            // 查询学校信息，筛选出符合大学类型要求的学校
            List<CollegeDO> colleges = collegeMapper.selectBySchoolUuids(schoolUuids);
            log.info("查询到 {} 条学校信息", colleges.size());

            // 筛选符合大学类型要求的学校UUID
            Set<String> validSchoolUuids = new HashSet<>();
            for (CollegeDO college : colleges) {
                if (isUniversityTypeMatch(college, universityTypes)) {
                    validSchoolUuids.add(college.getSchoolUuid());
                }
            }

            log.info("符合大学类型 '{}' 的学校数量: {}", universityTypes, validSchoolUuids.size());

            if (validSchoolUuids.isEmpty()) {
                log.warn("没有找到符合大学类型的学校");
                return new ArrayList<>();
            }

            // 过滤招生计划，只保留符合大学类型要求的学校
            List<CollegeEnrollmentPlanDO> filteredPlans = enrollmentPlans.stream()
                    .filter(plan -> validSchoolUuids.contains(plan.getSchoolUuid()))
                    .collect(Collectors.toList());

            log.info("按大学类型筛选完成，原始数量: {}, 过滤后数量: {}", enrollmentPlans.size(), filteredPlans.size());
            return filteredPlans;

        } catch (Exception e) {
            log.error("按大学类型筛选时发生错误", e);
            return enrollmentPlans; // 发生错误时返回原始数据
        }
    }

    /**
     * 检查学校是否符合大学类型要求
     * @param college 学校信息
     * @param universityTypes 大学类型列表
     * @return 是否匹配
     */
    private boolean isUniversityTypeMatch(CollegeDO college, List<String> universityTypes) {
        if (college == null || universityTypes == null || universityTypes.isEmpty()) {
            return false;
        }

        String collegeCategory = college.getCollegeCategory();
        if (collegeCategory == null) {
            return false;
        }

        for (String type : universityTypes) {
            if (collegeCategory.contains(type)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 去重专业录取信息列表
     * @param majors 专业录取信息列表
     * @return 去重后的列表
     */
    private List<MajorAdmissionInfo> deduplicateMajorAdmissionInfos(List<MajorAdmissionInfo> majors) {
        if (majors == null || majors.isEmpty()) {
            return new ArrayList<>();
        }

        // 使用学校名称+专业名称作为去重键
        Map<String, MajorAdmissionInfo> uniqueMajors = new LinkedHashMap<>();

        for (MajorAdmissionInfo major : majors) {
            String key = major.getSchoolName() + ":" + major.getMajorName();
            if (!uniqueMajors.containsKey(key)) {
                uniqueMajors.put(key, major);
            }
        }

        return new ArrayList<>(uniqueMajors.values());
    }

    /**
     * 第二步：根据招生计划结果查询专业录取分数线表
     * @param enrollmentPlans 符合条件的招生计划列表
     * @param profile 用户个人信息
     * @return 专业录取信息列表
     */
    private List<MajorAdmissionInfo> queryAdmissionScoresByEnrollmentPlans(List<CollegeEnrollmentPlanDO> enrollmentPlans, UserProfileInfo profile) {
        if (enrollmentPlans == null || enrollmentPlans.isEmpty()) {
            return new ArrayList<>();
        }

        String provinceName = profile.getProvince();
        Integer year = profile.getYear() != null ? profile.getYear() : 2024;
        String typeName = profile.getTypeName();

        // 计算分数范围
        int minScore = profile.getMinScore() != null ? profile.getMinScore() : profile.getTotalScore() - 60;
        int maxScore = profile.getMaxScore() != null ? profile.getMaxScore() : profile.getTotalScore() + 30;

        log.info("开始根据招生计划查询专业录取分数线 - 省份: {}, 年份: {}, 类型: {}, 分数范围: {}-{}",
                provinceName, year, typeName, minScore, maxScore);

        // 提取学校UUID和专业名称
        List<String> schoolUUIDs = new ArrayList<>();
        List<String> majorNames = new ArrayList<>();

        for (CollegeEnrollmentPlanDO plan : enrollmentPlans) {
            if (plan.getSchoolUuid() != null && !plan.getSchoolUuid().trim().isEmpty()) {
                schoolUUIDs.add(plan.getSchoolUuid());
            }
            if (plan.getCollegeMajorName() != null && !plan.getCollegeMajorName().trim().isEmpty()) {
                majorNames.add(plan.getCollegeMajorName());
            }
        }

        // 去重
        schoolUUIDs = schoolUUIDs.stream().distinct().collect(Collectors.toList());
        majorNames = majorNames.stream().distinct().collect(Collectors.toList());

        log.info("提取到 {} 个学校UUID，{} 个专业名称", schoolUUIDs.size(), majorNames.size());

        try {
            // 批量查询专业录取分数数据
            List<MajorAdmissionDO> admissionDOList = majorAdmissionMapper
                    .batchSelectAdmissionScoresSimple(schoolUUIDs, majorNames, year, typeName, provinceName);

            log.info("批量查询得到 {} 条专业录取分数数据", admissionDOList.size());

            // 过滤分数范围
            List<MajorAdmissionDO> filteredAdmissions = admissionDOList.stream()
                    .filter(admission -> {
                        try {
                            String lowestScore = admission.getLowestScore();
                            if (lowestScore != null && !lowestScore.trim().isEmpty()) {
                                int score = Integer.parseInt(lowestScore.trim());
                                return score >= minScore && score <= maxScore;
                            }
                        } catch (NumberFormatException e) {
                            log.debug("无法解析分数: {}", admission.getLowestScore());
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            log.info("分数范围过滤后剩余 {} 条数据", filteredAdmissions.size());

            // 转换为 MajorAdmissionInfo
            List<MajorAdmissionInfo> admissionInfos = new ArrayList<>();
            for (MajorAdmissionDO admission : filteredAdmissions) {
                MajorAdmissionInfo info = convertToMajorAdmissionInfo(admission);

                // 从招生计划中获取额外信息并设置到 enrollmentPlanData 中
                CollegeEnrollmentPlanDO matchedPlan = findMatchingEnrollmentPlan(enrollmentPlans, admission);
                if (matchedPlan != null) {
                    // 将招生计划信息转换为 CollegeEnrollmentPlanInfo 并设置到 enrollmentPlanData
                    CollegeEnrollmentPlanInfo planInfo = convertToCollegeEnrollmentPlanInfo(matchedPlan);
                    info.setEnrollmentPlanData(Arrays.asList(planInfo));

                    // 更新 batchName（如果招生计划中有更准确的信息）
                    if (matchedPlan.getBatchName() != null && !matchedPlan.getBatchName().trim().isEmpty()) {
                        info.setBatchName(matchedPlan.getBatchName());
                    }
                }

                admissionInfos.add(info);
            }

            log.info("最终转换得到 {} 条专业录取信息", admissionInfos.size());
            return admissionInfos;

        } catch (Exception e) {
            log.error("根据招生计划查询专业录取分数线时发生错误", e);
            return new ArrayList<>();
        }
    }

    /**
     * 查找匹配的招生计划
     * @param enrollmentPlans 招生计划列表
     * @param admission 专业录取数据
     * @return 匹配的招生计划，没有则返回null
     */
    private CollegeEnrollmentPlanDO findMatchingEnrollmentPlan(List<CollegeEnrollmentPlanDO> enrollmentPlans, MajorAdmissionDO admission) {
        for (CollegeEnrollmentPlanDO plan : enrollmentPlans) {
            // 匹配学校UUID和专业名称
            if (Objects.equals(plan.getSchoolUuid(), admission.getSchoolUuid())
                    && isMajorNameMatch(plan.getCollegeMajorName(), admission.getMajorName())) {
                return plan;
            }
        }
        return null;
    }

    /**
     * 获取专业组标识（使用智能匹配逻辑，统一使用数字部分）
     * @param info 专业录取信息
     * @return 专业组标识
     */
    private String getMajorGroupKey(MajorAdmissionInfo info) {
        String schoolKey = info.getSchoolUUID();
        String majorGroupKey = "";
        
        // 优先使用招生计划中的专业组信息（如（01）、（02）等）
        if (info.getEnrollmentPlanData() != null && !info.getEnrollmentPlanData().isEmpty()) {
            // 从招生计划数据中获取专业组信息
            String specialGroupName = info.getEnrollmentPlanData().get(0).getSpecialGroupName();
            if (specialGroupName != null && !specialGroupName.trim().isEmpty()) {
                // 使用智能匹配逻辑提取专业组编号，优先使用数字部分
                String extractedCode = extractSpecialGroupCode(specialGroupName.trim());
                if (extractedCode != null) {
                    // 进一步提取数字部分作为统一的分组键
                    String numberPart = extractNumberPart(extractedCode);
                    majorGroupKey = numberPart != null ? numberPart : extractedCode;
                } else {
                    majorGroupKey = specialGroupName.trim();
                }
                log.debug("专业 {} 使用招生计划专业组: {} -> 提取编号: {} -> 数字部分: {}", 
                        info.getMajorName(), specialGroupName, extractedCode, majorGroupKey);
                return schoolKey + "_" + majorGroupKey;
            }
        }
        
        // 备选方案：使用subjectGroup字段作为专业组标识
        if (info.getSubjectGroup() != null && !info.getSubjectGroup().trim().isEmpty()) {
            // 使用智能匹配逻辑提取专业组编号，优先使用数字部分
            String extractedCode = extractSpecialGroupCode(info.getSubjectGroup().trim());
            if (extractedCode != null) {
                // 进一步提取数字部分作为统一的分组键
                String numberPart = extractNumberPart(extractedCode);
                majorGroupKey = numberPart != null ? numberPart : extractedCode;
            } else {
                majorGroupKey = info.getSubjectGroup().trim();
            }
            log.debug("专业 {} 使用subjectGroup专业组: {} -> 提取编号: {} -> 数字部分: {}", 
                    info.getMajorName(), info.getSubjectGroup(), extractedCode, majorGroupKey);
        } else if (info.getMajorCode() != null && info.getMajorCode().length() >= 3) {
            // 备选方案1：使用专业代码前3位
            majorGroupKey = info.getMajorCode().substring(0, 3);
        } else {
            // 备选方案2：使用专业名称核心部分
            majorGroupKey = extractCoreMajorName(info.getMajorName());
        }
        
        String finalKey = schoolKey + "_" + majorGroupKey;
        log.debug("专业 {} 的专业组键: {}", info.getMajorName(), finalKey);
        return finalKey;
    }

    /**
     * 提取专业名称核心部分（去除括号内容）
     * @param majorName 专业名称
     * @return 核心专业名称
     */
    private String extractCoreMajorName(String majorName) {
        if (majorName == null) return "";
        // 去除括号及其内容
        return majorName.replaceAll("[（(].*?[）)]", "").trim();
    }

    /**
     * 计算专业组平均分
     * @param majorGroup 专业组内的专业列表
     * @return 专业组平均分
     */
    private double calculateMajorGroupAverageScore(List<MajorAdmissionInfo> majorGroup, int userScore) {
        List<Integer> validScores = new ArrayList<>();
        boolean hasNewMajors = false;
        
        for (MajorAdmissionInfo info : majorGroup) {
            // 检查是否为2025年新增专业
            if ("NEW_MAJOR_2025".equals(info.getProScore())) {
                hasNewMajors = true;
                // 新增专业没有历史录取分数，跳过分数计算
                continue;
            }
            
            try {
                String lowestScore = info.getLowestScore();
                if (lowestScore != null && !lowestScore.trim().isEmpty()) {
                    validScores.add(Integer.parseInt(lowestScore.trim()));
                }
            } catch (NumberFormatException e) {
                log.debug("无法解析专业录取分数: {}", info.getLowestScore());
            }
        }
        
        // 如果专业组中只有新增专业，没有历史录取分数
        if (validScores.isEmpty()) {
            if (hasNewMajors) {
                // 对于纯新增专业组，返回一个接近用户分数的值，使其归类为稳妥
                // 这样可以确保新增专业出现在用户常请求的等级中
                log.debug("专业组只包含新增专业，使用用户分数{}作为默认分数进行分类", userScore);
                return userScore; // 使用用户分数，使新增专业归类为稳妥
            }
            return 0.0;
        }
        
        return validScores.stream().mapToInt(Integer::intValue).average().orElse(0.0);
    }

    /**
     * 统计专业列表中包含的专业组数量
     */
    private long countGroups(List<MajorAdmissionInfo> majors) {
        return majors.stream()
            .map(this::getMajorGroupKey)
            .distinct()
            .count();
    }

    /**
     * 第三步：按专业组进行冲稳保分组
     * @param admissionInfos 专业录取信息列表
     * @param userScore 用户分数
     * @return 分组后的专业列表
     */
    private Map<String, List<MajorAdmissionInfo>> classifyMajorsByScore(List<MajorAdmissionInfo> admissionInfos, int userScore) {
        Map<String, List<MajorAdmissionInfo>> result = new HashMap<>();
        List<MajorAdmissionInfo> rushMajors = new ArrayList<>();
        List<MajorAdmissionInfo> stableMajors = new ArrayList<>();
        List<MajorAdmissionInfo> safeMajors = new ArrayList<>();


        // 检查传入的专业列表中是否包含新增专业
        long newMajorCount = admissionInfos.stream()
                .filter(major -> "NEW_MAJOR_2025".equals(major.getProScore()))
                .count();

        if (newMajorCount > 0) {
            admissionInfos.stream()
                    .filter(major -> "NEW_MAJOR_2025".equals(major.getProScore()))
                    .forEach(major -> log.info("传入的新增专业：{} - {}", major.getSchoolName(), major.getMajorName()));
        }

        // 第一步：按专业组分组
        Map<String, List<MajorAdmissionInfo>> majorGroups = admissionInfos.stream()
            .collect(Collectors.groupingBy(this::getMajorGroupKey));


        // 第二步：按专业组平均分进行分类
        for (Map.Entry<String, List<MajorAdmissionInfo>> entry : majorGroups.entrySet()) {
            String groupKey = entry.getKey();
            List<MajorAdmissionInfo> groupMajors = entry.getValue();
            
            // 计算专业组平均分
            double groupAverageScore = calculateMajorGroupAverageScore(groupMajors, userScore);
            

            // 检查专业组中是否包含新增专业
            boolean hasNewMajorsInGroup = groupMajors.stream()
                    .anyMatch(major -> "NEW_MAJOR_2025".equals(major.getProScore()));
            
            // 根据专业组平均分进行分类
            // 分类逻辑：
            // 冲刺：专业组平均分 > 用户分数 + 5
            // 稳妥：用户分数 - 5 <= 专业组平均分 <= 用户分数 + 5
            // 保底：专业组平均分 < 用户分数 - 5
            if (groupAverageScore > userScore + 5) {
                rushMajors.addAll(groupMajors);

            } else if (groupAverageScore >= userScore - 5 && groupAverageScore <= userScore + 5) {
                stableMajors.addAll(groupMajors);

            } else if (groupAverageScore < userScore - 5) {
                safeMajors.addAll(groupMajors);

            }
        }

        result.put("rush", rushMajors);
        result.put("stable", stableMajors);
        result.put("safe", safeMajors);

        return result;
    }

    /**
     * 限制专业数量，如果超过10个则保留与用户分数最接近的10个
     * @param majors 专业列表
     * @param userScore 用户分数
     * @param levelName 等级名称（用于日志）
     * @return 限制后的专业列表
     */
    private List<MajorAdmissionInfo> limitMajorsByClosestScore(List<MajorAdmissionInfo> majors, int userScore, String levelName) {
        if (majors == null || majors.size() <= 10) {
            return majors;
        }

        log.info("{}等级专业数量超过10个（{}个），开始按分数接近程度筛选最接近的10个", levelName, majors.size());

        // 按照与用户分数的绝对差值排序，差值越小越靠前
        List<MajorAdmissionInfo> sortedMajors = majors.stream()
                .sorted((m1, m2) -> {
                    try {
                        int score1 = Integer.parseInt(m1.getLowestScore().trim());
                        int score2 = Integer.parseInt(m2.getLowestScore().trim());

                        int diff1 = Math.abs(score1 - userScore);
                        int diff2 = Math.abs(score2 - userScore);

                        // 首先按分数差值排序
                        int diffComparison = Integer.compare(diff1, diff2);
                        if (diffComparison != 0) {
                            return diffComparison;
                        }

                        // 如果分数差值相同，按专业分数排序（保持稳定性）
                        return Integer.compare(score1, score2);
                    } catch (NumberFormatException e) {
                        // 无法解析分数的专业排在后面
                        return 1;
                    }
                })
                .collect(Collectors.toList());

        // 取前10个
        List<MajorAdmissionInfo> limitedMajors = sortedMajors.subList(0, 10);

        log.info("{}等级专业筛选完成，从{}个筛选到{}个", levelName, majors.size(), limitedMajors.size());

        return limitedMajors;
    }

    /**
     * 直接参数版本的招生计划过滤
     */
    private List<MajorAdmissionInfo> batchFilterDirectParamsEnrollmentPlans(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return new ArrayList<>();
        }

        long startTime = System.currentTimeMillis();
        log.info("开始直接参数版本招生计划过滤，原始专业数量: {}", majors.size());

        try {
            // 提取所有不重复的学校名称和专业名称
            List<String> schoolNames = majors.stream()
                    .map(MajorAdmissionInfo::getSchoolName)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            List<String> majorNames = majors.stream()
                    .map(MajorAdmissionInfo::getMajorName)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            log.info("提取到 {} 个不重复学校名称，{} 个不重复专业名称", schoolNames.size(), majorNames.size());

            // 查询2022-2024年的招生计划数据
            List<CollegeEnrollmentPlanDO> existingPlans = collegeEnrollmentPlanService
                    .batchCheckEnrollmentPlansMultiYear(schoolNames, majorNames, profile.getProvince());

            log.info("查询到 {} 条招生计划数据", existingPlans.size());

            if (existingPlans.isEmpty()) {
                log.warn("未找到任何招生计划数据");
                return new ArrayList<>();
            }

            // 构建招生计划映射
            Set<String> validCombinations = existingPlans.stream()
                    .map(plan -> plan.getSchoolName() + ":" + plan.getCollegeMajorName())
                    .collect(Collectors.toSet());

            log.info("有效的招生计划组合: {}", validCombinations.size());

            // 过滤出有招生计划的专业
            List<MajorAdmissionInfo> filteredList = majors.stream()
                    .filter(admission -> {
                        // 检查是否有匹配的招生计划
                        for (String combination : validCombinations) {
                            String[] parts = combination.split(":", 2);
                            if (parts.length == 2 && parts[0].equals(admission.getSchoolName())) {
                                String planMajorName = parts[1];
                                if (isMajorNameMatch(admission.getMajorName(), planMajorName)) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    })
                    .collect(Collectors.toList());

            long endTime = System.currentTimeMillis();
            log.info("直接参数版本招生计划过滤完成，原始数量: {}, 过滤后数量: {}, 耗时: {}ms",
                     majors.size(), filteredList.size(), endTime - startTime);

            return filteredList;

        } catch (Exception e) {
            log.error("直接参数版本招生计划过滤时发生错误", e);
            return new ArrayList<>();
        }
    }

    /**
     * 直接参数版本的选科筛选
     */
    private List<MajorAdmissionInfo> filterDirectParamsBySubjectSelection(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return new ArrayList<>();
        }

        // 如果用户没有选科信息，直接返回
        if (profile.getSubjects() == null || profile.getSubjects().isEmpty()) {
            log.info("用户未提供选科信息，跳过选科筛选");
            return majors;
        }

        log.info("开始直接参数版本选科筛选，原始专业数量: {}", majors.size());

        Set<String> userSubjects = new HashSet<>(profile.getSubjects());
        log.info("用户选科信息: {}", userSubjects);

        List<MajorAdmissionInfo> filteredBySubjects = new ArrayList<>();
        int filteredCount = 0;

        for (MajorAdmissionInfo info : majors) {
            boolean passesSubjectCheck = true;

            // 检查基本的选科要求
            if (info.getSubjectSelection() != null && !info.getSubjectSelection().trim().isEmpty()) {
                if (!checkSubjectRequirements(userSubjects, info.getSubjectSelection())) {
                    passesSubjectCheck = false;
                }
            }

            // 检查招生计划数据中的选科要求
            if (passesSubjectCheck && info.getEnrollmentPlanData() != null && !info.getEnrollmentPlanData().isEmpty()) {
                boolean hasValidEnrollmentPlan = false;
                for (CollegeEnrollmentPlanInfo planInfo : info.getEnrollmentPlanData()) {
                    if (checkSubjectRequirements(userSubjects, planInfo.getCourseSelectionRequirements())) {
                        hasValidEnrollmentPlan = true;
                        break;
                    }
                }
                if (!hasValidEnrollmentPlan) {
                    log.debug("专业 {} - {} 的所有招生计划都不符合用户选科要求，用户选科: {}",
                            info.getSchoolName(), info.getMajorName(), userSubjects);
                    passesSubjectCheck = false;
                }
            }

            if (passesSubjectCheck) {
                filteredBySubjects.add(info);
            } else {
                filteredCount++;
            }
        }

        log.info("直接参数版本选科筛选完成 - 原始数量: {}，过滤掉: {}，保留: {}",
                majors.size(), filteredCount, filteredBySubjects.size());
        return filteredBySubjects;
    }

    /**
     * 直接参数版本的专业分类（按冲稳保）
     */
    private Map<String, List<MajorAdmissionInfo>> classifyDirectParamsMajors(List<MajorAdmissionInfo> majors, int userScore) {
        Map<String, List<MajorAdmissionInfo>> result = new HashMap<>();
        List<MajorAdmissionInfo> rushMajors = new ArrayList<>();    // 冲刺：分数高于用户分数
        List<MajorAdmissionInfo> stableMajors = new ArrayList<>();  // 稳妥：分数接近用户分数
        List<MajorAdmissionInfo> safeMajors = new ArrayList<>();    // 保底：分数低于用户分数

        for (MajorAdmissionInfo major : majors) {
            try {
                int majorScore = Integer.parseInt(major.getLowestScore());
                int scoreDiff = majorScore - userScore;

                if (scoreDiff > 5) {
                    // 冲刺：专业分数比用户分数高5分以上
                    rushMajors.add(major);
                } else if (scoreDiff >= -5 && scoreDiff <= 5) {
                    // 稳妥：专业分数在用户分数±5分范围内
                    stableMajors.add(major);
                } else if (scoreDiff < -5) {
                    // 保底：专业分数比用户分数低5分以上
                    safeMajors.add(major);
                }
            } catch (NumberFormatException e) {
                // 无法解析分数的专业放入稳妥类别
                stableMajors.add(major);
                log.warn("无法解析专业分数: {} - {}", major.getSchoolName(), major.getMajorName());
            }
        }

        // 按分数排序
        Comparator<MajorAdmissionInfo> scoreComparator = (m1, m2) -> {
            try {
                int score1 = Integer.parseInt(m1.getLowestScore());
                int score2 = Integer.parseInt(m2.getLowestScore());
                return Integer.compare(score1, score2);
            } catch (NumberFormatException e) {
                return 0;
            }
        };

        rushMajors.sort(scoreComparator);
        stableMajors.sort(scoreComparator);
        safeMajors.sort(scoreComparator);

        result.put("rush", rushMajors);
        result.put("stable", stableMajors);
        result.put("safe", safeMajors);

        log.info("直接参数版本专业分类完成 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                rushMajors.size(), stableMajors.size(), safeMajors.size());

        return result;
    }

    /**
     * 构建直接参数版本的空结果
     */
    private Map<String, Object> buildEmptyDirectParamsResult(UserProfileInfo profile, StringBuilder queryInfo) {
        Map<String, Object> result = new HashMap<>();
        result.put("rushMajors", new ArrayList<>());
        result.put("stableMajors", new ArrayList<>());
        result.put("safeMajors", new ArrayList<>());
        result.put("rushCount", 0);
        result.put("stableCount", 0);
        result.put("safeCount", 0);
        result.put("totalCount", 0);

        // 构建查询信息
        buildDirectParamsQueryInfo(profile, queryInfo, 0, 0, 0);
        result.put("queryInfo", queryInfo.toString());

        log.info("返回空的直接参数版本结果");
        return result;
    }

    /**
     * 构建直接参数版本的查询信息
     */
    private void buildDirectParamsQueryInfo(UserProfileInfo profile, StringBuilder queryInfo,
                                          int rushCount, int stableCount, int safeCount) {
        queryInfo.append("查询条件：\n");
        queryInfo.append("• 省份：").append(profile.getProvince()).append("\n");
        queryInfo.append("• 分数：").append(profile.getTotalScore()).append("分\n");

        if (profile.getSubjects() != null && !profile.getSubjects().isEmpty()) {
            queryInfo.append("• 选科：").append(String.join(",", profile.getSubjects())).append("\n");
        }

        if (profile.getMinScore() != null && profile.getMaxScore() != null) {
            queryInfo.append("• 分数范围：").append(profile.getMinScore()).append("-")
                    .append(profile.getMaxScore()).append("分（用户自定义）\n");
        } else {
            int defaultMin = profile.getTotalScore() - 60;
            int defaultMax = profile.getTotalScore() + 30;
            queryInfo.append("• 分数范围：").append(defaultMin).append("-")
                    .append(defaultMax).append("分（默认范围）\n");
        }

        if (profile.getInterestedMajorCategories() != null && !profile.getInterestedMajorCategories().isEmpty()) {
            queryInfo.append("• 意向专业：").append(String.join(",", profile.getInterestedMajorCategories())).append("\n");
        }

        if (profile.getGender() != null) {
            queryInfo.append("• 性别：").append(profile.getGender()).append("\n");
        }

        if (profile.getPreferredLocation() != null) {
            queryInfo.append("• 期望地区：").append(profile.getPreferredLocation()).append("\n");
        }

        if (profile.getBatchName() != null) {
            queryInfo.append("• 录取批次：").append(profile.getBatchName()).append("\n");
        }

        if (profile.getSchoolName() != null) {
            queryInfo.append("• 学校名称：").append(profile.getSchoolName()).append("\n");
        }

        if (profile.getSchoolFeatures() != null && !profile.getSchoolFeatures().isEmpty()) {
            queryInfo.append("• 院校特色：").append(String.join(",", profile.getSchoolFeatures())).append("\n");
        }

        if (profile.getSchoolProperties() != null && !profile.getSchoolProperties().isEmpty()) {
            queryInfo.append("• 办学性质：").append(String.join(",", profile.getSchoolProperties())).append("\n");
        }

        if (profile.getSchoolTypes() != null && !profile.getSchoolTypes().isEmpty()) {
            queryInfo.append("• 大学类型：").append(String.join(",", profile.getSchoolTypes())).append("\n");
        }

        queryInfo.append("\n查询结果：\n");
        queryInfo.append("• 冲刺专业：").append(rushCount).append("个\n");
        queryInfo.append("• 稳妥专业：").append(stableCount).append("个\n");
        queryInfo.append("• 保底专业：").append(safeCount).append("个\n");
        queryInfo.append("• 总计：").append(rushCount + stableCount + safeCount).append("个专业\n");

        queryInfo.append("\n说明：\n");
        queryInfo.append("• 冲刺专业：录取分数比您的分数高5分以上，有一定挑战性\n");
        queryInfo.append("• 稳妥专业：录取分数在您的分数±5分范围内，录取概率较高\n");
        queryInfo.append("• 保底专业：录取分数比您的分数低5分以上，录取概率很高");
    }

    /**
     * 根据直接参数获取所有适合的专业（支持分组）- 兼容性方法
     * @param profile 用户个人信息
     * @param groupType 分组类型：school-按学校分组，major-按专业分组
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param levelTypes 要返回的等级类型列表，为空时默认只返回冲刺等级
     * @return 分组查询结果
     */
    public DirectParamsGroupRespVO getAllSuitableMajorsByDirectParamsWithGroup(UserProfileInfo profile,
                                                                               String groupType,
                                                                               Integer pageNo,
                                                                               Integer pageSize,
                                                                               List<String> levelTypes) {
        return getAllSuitableMajorsByDirectParamsWithGroup(profile, groupType, pageNo, pageSize, levelTypes, true, null);
    }

    /**
     * 根据直接参数获取所有适合的专业（支持分组）
     * @param profile 用户个人信息
     * @param groupType 分组类型：school-按学校分组，major-按专业分组
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param levelTypes 要返回的等级类型列表，为空时默认只返回冲刺等级
     * @param includeMajorDetails 是否返回详细专业数据
     * @param targetSchoolUuid 指定学校UUID（可选）
     * @return 分组查询结果
     */
    public DirectParamsGroupRespVO getAllSuitableMajorsByDirectParamsWithGroup(UserProfileInfo profile,
                                                                               String groupType,
                                                                               Integer pageNo,
                                                                               Integer pageSize,
                                                                               List<String> levelTypes,
                                                                               Boolean includeMajorDetails,
                                                                               String targetSchoolUuid) {
        // 调用优化版本的方法
        return getAllSuitableMajorsByDirectParamsWithGroupOptimizedV2(profile, groupType, pageNo, pageSize,
                levelTypes, includeMajorDetails, targetSchoolUuid);
    }

    /**
     * 根据直接参数获取所有适合的专业（支持分组，性能优化版本V2）
     * 优化策略：
     * 1. 按学校分组时，先获取不重复的学校信息，再根据分页处理
     * 2. 按专业分组时，先获取不重复的专业名称，再根据分页处理
     * 3. 历史数据查询只查询最新一年（2024年）
     * @param profile 用户个人信息
     * @param groupType 分组类型：school-按学校分组，major-按专业分组
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param levelTypes 要返回的等级类型列表，为空时默认只返回冲刺等级
     * @param includeMajorDetails 是否返回详细专业数据
     * @param targetSchoolUuid 指定学校UUID（可选）
     * @return 分组查询结果
     */
    public DirectParamsGroupRespVO getAllSuitableMajorsByDirectParamsWithGroupOptimizedV2(UserProfileInfo profile,
                                                                                          String groupType,
                                                                                          Integer pageNo,
                                                                                          Integer pageSize,
                                                                                          List<String> levelTypes,
                                                                                          Boolean includeMajorDetails,
                                                                                          String targetSchoolUuid) {
        long startTime = System.currentTimeMillis();
        log.info("开始分组查询所有适合专业（性能优化版本V2），分组类型：{}，用户省份：{}，分数：{}，请求等级：{}",
                groupType, profile.getProvince(), profile.getTotalScore(), levelTypes);

        // 设置默认分页参数
        if (pageNo == null || pageNo < 1) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10;
        }

        DirectParamsGroupRespVO result = new DirectParamsGroupRespVO();
        result.setGroupType(groupType);

        try {
            if ("school".equals(groupType)) {
                // 按学校分组的优化查询
                return getSchoolGroupedMajorsOptimized(profile, pageNo, pageSize, levelTypes, includeMajorDetails, targetSchoolUuid);
            } else if ("major".equals(groupType)) {
                // 按专业分组的优化查询
                return getMajorGroupedSchoolsOptimized(profile, pageNo, pageSize, levelTypes);
            } else {
                // 原有逻辑作为兜底
                return getAllSuitableMajorsByDirectParamsWithGroupOriginal(profile, groupType, pageNo, pageSize,
                        levelTypes, includeMajorDetails, targetSchoolUuid);
            }
        } catch (Exception e) {
            log.error("分组查询所有适合专业时发生错误（性能优化版本V2）", e);
            result.setQueryInfo("查询过程中发生错误：" + e.getMessage());
            return result;
        }
    }

    /**
     * 原有的分组查询方法（保持兼容性）
     */
    private DirectParamsGroupRespVO getAllSuitableMajorsByDirectParamsWithGroupOriginal(UserProfileInfo profile,
                                                                                        String groupType,
                                                                                        Integer pageNo,
                                                                                        Integer pageSize,
                                                                                        List<String> levelTypes,
                                                                                        Boolean includeMajorDetails,
                                                                                        String targetSchoolUuid) {
        long startTime = System.currentTimeMillis();
        log.info("开始分组查询所有适合专业（原有版本），分组类型：{}，用户省份：{}，分数：{}",
                groupType, profile.getProvince(), profile.getTotalScore());

        DirectParamsGroupRespVO result = new DirectParamsGroupRespVO();
        result.setGroupType(groupType);

        try {

            // 先获取所有符合条件的专业数据，传递 levelTypes 参数
            Map<String, Object> allMajorsResult = getAllSuitableMajorsByDirectParams(profile, levelTypes);

            List<MajorAdmissionInfo> rushMajorsGugu = (List<MajorAdmissionInfo>) allMajorsResult.get("rushMajors");
            List<MajorAdmissionInfo> stableMajorsGugu = (List<MajorAdmissionInfo>) allMajorsResult.get("stableMajors");
            List<MajorAdmissionInfo> safeMajorsGugu = (List<MajorAdmissionInfo>) allMajorsResult.get("safeMajors");
            String queryInfo = (String) allMajorsResult.get("queryInfo");

            // 转换为DirectParamsGroupRespVO.MajorAdmissionInfo类型
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajors = convertToDirectParamsMajorAdmissionInfo(rushMajorsGugu);
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajors = convertToDirectParamsMajorAdmissionInfo(stableMajorsGugu);
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajors = convertToDirectParamsMajorAdmissionInfo(safeMajorsGugu);

            // 合并所有专业数据
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> allMajors = new ArrayList<>();
            allMajors.addAll(rushMajors);
            allMajors.addAll(stableMajors);
            allMajors.addAll(safeMajors);

            if (allMajors.isEmpty()) {
                result.setQueryInfo(queryInfo);
                log.info("未找到符合条件的专业数据，返回空结果");
                return result;
            }

            // 根据分组类型进行分组处理
            if ("school".equals(groupType)) {
                // 按学校分组并按冲稳保分类
                DirectParamsGroupRespVO.SchoolClassificationData schoolClassification =
                    classifySchoolsByLevel(allMajors, rushMajors, stableMajors, safeMajors, pageNo, pageSize, profile, levelTypes);
                result.setSchoolClassification(schoolClassification);

                // 保持原有的分组格式（兼容性），传递专业详情参数
                PageResult<DirectParamsGroupRespVO.SchoolGroupData> schoolGroups =
                    groupMajorsBySchool(allMajors, rushMajors, stableMajors, safeMajors, pageNo, pageSize, profile,
                                      includeMajorDetails, targetSchoolUuid);
                result.setSchoolGroups(schoolGroups);
            } else if ("major".equals(groupType)) {
                // 按专业分组并按冲稳保分类
                DirectParamsGroupRespVO.MajorClassificationData majorClassification =
                    classifyMajorsByLevel(allMajors, rushMajors, stableMajors, safeMajors, pageNo, pageSize, levelTypes);
                result.setMajorClassification(majorClassification);

                // 保持原有的分组格式（兼容性）
                PageResult<DirectParamsGroupRespVO.MajorGroupData> majorGroups =
                    groupMajorsByMajor(allMajors, rushMajors, stableMajors, safeMajors, pageNo, pageSize);
                result.setMajorGroups(majorGroups);
            } else {
                throw new IllegalArgumentException("不支持的分组类型: " + groupType);
            }

            result.setQueryInfo(queryInfo);

            long endTime = System.currentTimeMillis();
            log.info("分组查询完成，分组类型：{}，耗时：{}ms", groupType, endTime - startTime);

        } catch (Exception e) {
            log.error("分组查询所有适合专业时发生错误", e);
            result.setQueryInfo("查询过程中发生错误：" + e.getMessage());
        }

        return result;
    }

    /**
     * 按学校分组的优化查询方法
     * 优化策略：第一步从专业录取数据表中获取适合用户的专业数据，直接统计冲稳保等级数量
     */
    private DirectParamsGroupRespVO getSchoolGroupedMajorsOptimized(UserProfileInfo profile,
                                                                   Integer pageNo,
                                                                   Integer pageSize,
                                                                   List<String> levelTypes,
                                                                   Boolean includeMajorDetails,
                                                                   String targetSchoolUuid) {
        long startTime = System.currentTimeMillis();

        DirectParamsGroupRespVO result = new DirectParamsGroupRespVO();
        result.setGroupType("school");

            // 第一步：直接从专业录取数据表获取适合用户的专业数据
            List<MajorAdmissionDO> admissionData = getFilteredMajorAdmissionData(profile, targetSchoolUuid);
            if (admissionData.isEmpty()) {
                result.setQueryInfo("未找到符合条件的专业录取数据");
                return result;
            }

            // 第二步：转换为 MajorAdmissionInfo 对象并进行严格去重
            List<MajorAdmissionInfo> majorInfos = admissionData.stream()
                    .map(this::convertToMajorAdmissionInfo)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());

            // 第二步补充：获取2025年招生计划中的新增专业（没有2024年录取数据的专业）
            try {
                List<MajorAdmissionInfo> newMajorsFromPlan = getNewMajorsFromEnrollmentPlan(majorInfos, profile, targetSchoolUuid);
                
                if (!newMajorsFromPlan.isEmpty()) {
                    majorInfos.addAll(newMajorsFromPlan);
                }
            } catch (Exception e) {
                // 忽略新增专业获取错误，继续使用现有数据
            }

            // 按冲稳保分类
            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByScore(majorInfos, profile.getTotalScore());
            List<MajorAdmissionInfo> rushMajors = classifiedMajors.get("rush");
            List<MajorAdmissionInfo> stableMajors = classifiedMajors.get("stable");
            List<MajorAdmissionInfo> safeMajors = classifiedMajors.get("safe");

            // 统计学校数量（按学校分组时应该统计学校数量而不是专业数量）
            Set<String> rushSchoolUuids = rushMajors.stream()
                    .map(MajorAdmissionInfo::getSchoolUUID)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Set<String> stableSchoolUuids = stableMajors.stream()
                    .map(MajorAdmissionInfo::getSchoolUUID)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Set<String> safeSchoolUuids = safeMajors.stream()
                    .map(MajorAdmissionInfo::getSchoolUUID)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());



            // 第三步：根据用户传递的等级从不同的冲稳保分类中获取不重复的学校信息
            // 处理 levelTypes 参数，默认返回所有等级
            Set<String> requestedLevels = new HashSet<>();
            if (levelTypes == null || levelTypes.isEmpty()) {
                requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            } else {
                requestedLevels.addAll(levelTypes);
            }

            // 根据用户请求的等级从对应分类中获取学校
            // 使用 LinkedHashMap 保证插入顺序，确保分页结果的一致性
            Map<String, String> uniqueSchools = new LinkedHashMap<>();

            if (requestedLevels.contains("rush")) {
                rushMajors.stream()
                    .filter(major -> major.getSchoolUUID() != null)
                    .forEach(major ->
                        uniqueSchools.put(major.getSchoolUUID(), major.getSchoolName()));
            }

            if (requestedLevels.contains("stable")) {
                stableMajors.stream()
                    .filter(major -> major.getSchoolUUID() != null)
                    .forEach(major ->
                        uniqueSchools.put(major.getSchoolUUID(), major.getSchoolName()));
            }

            if (requestedLevels.contains("safe")) {
                safeMajors.stream()
                    .filter(major -> major.getSchoolUUID() != null)
                    .forEach(major ->
                        uniqueSchools.put(major.getSchoolUUID(), major.getSchoolName()));
            }



            // 检查是否有符合条件的学校数据
            if (uniqueSchools.isEmpty()) {
                result.setQueryInfo("在请求的等级中未找到符合条件的学校数据，但其他等级有数据");
                result.setSchoolGroups(new PageResult<>(new ArrayList<>(), 0L));
                result.setTotalCount(0);
                result.setPageNo(pageNo);
                result.setPageSize(pageSize);
                result.setTotalPages(0);

                // 设置真实的分类统计数据（显示其他等级的数据量）
                DirectParamsGroupRespVO.SchoolClassificationData schoolClassification =
                        new DirectParamsGroupRespVO.SchoolClassificationData();
                schoolClassification.setRushCount(rushSchoolUuids.size());
                schoolClassification.setStableCount(stableSchoolUuids.size());
                schoolClassification.setSafeCount(safeSchoolUuids.size());
                schoolClassification.setTotalCount(rushSchoolUuids.size() + stableSchoolUuids.size() + safeSchoolUuids.size());

                // 不设置学校列表，避免性能问题
                schoolClassification.setRushSchools(new ArrayList<>());
                schoolClassification.setStableSchools(new ArrayList<>());
                schoolClassification.setSafeSchools(new ArrayList<>());
                result.setSchoolClassification(schoolClassification);



                return result;
            }

            // 第四步：分页处理学校
            // 对学校UUID进行排序，确保分页结果的一致性和稳定性
            List<String> schoolUuids = new ArrayList<>(uniqueSchools.keySet());
            // 过滤掉null值，避免排序时出现NullPointerException
            schoolUuids = schoolUuids.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            schoolUuids.sort(String::compareTo); // 按UUID字典序排序，确保每次查询结果顺序一致

            int totalSchools = schoolUuids.size();
            int start = (pageNo - 1) * pageSize;
            int end = Math.min(start + pageSize, totalSchools);



            if (start >= totalSchools) {
                result.setQueryInfo("页码超出范围，请求的等级中共有 " + totalSchools + " 个学校，但请求的页码超出范围");
                return result;
            }

            List<String> pagedSchoolUuids = schoolUuids.subList(start, end);

            // 第五步：为当前页的学校构建分组数据（基于已分类的专业数据）
            List<DirectParamsGroupRespVO.SchoolGroupData> schoolGroups = new ArrayList<>();
            for (String schoolUuid : pagedSchoolUuids) {
                String schoolName = uniqueSchools.get(schoolUuid);
                DirectParamsGroupRespVO.SchoolGroupData schoolGroup = buildSchoolGroupDataFromClassifiedMajors(
                        schoolUuid, schoolName, majorInfos, rushMajors, stableMajors, safeMajors,
                        levelTypes, includeMajorDetails, profile);
                if (schoolGroup != null && schoolGroup.getTotalCount() > 0) {
                    schoolGroups.add(schoolGroup);
                }
            }

            // 第六步：构建冲稳保分类统计数据（只计算统计数量，不返回完整学校列表以提升性能）
            DirectParamsGroupRespVO.SchoolClassificationData schoolClassification =
                    new DirectParamsGroupRespVO.SchoolClassificationData();

            // 设置统计数量
            schoolClassification.setRushCount(rushSchoolUuids.size());
            schoolClassification.setStableCount(stableSchoolUuids.size());
            schoolClassification.setSafeCount(safeSchoolUuids.size());
            schoolClassification.setTotalCount(rushSchoolUuids.size() + stableSchoolUuids.size() + safeSchoolUuids.size());

            // 不设置学校列表，避免性能问题（如果需要完整列表，可以通过其他接口获取）
            schoolClassification.setRushSchools(new ArrayList<>());
            schoolClassification.setStableSchools(new ArrayList<>());
            schoolClassification.setSafeSchools(new ArrayList<>());

            result.setSchoolClassification(schoolClassification);

            // 第七步：构建返回结果
            PageResult<DirectParamsGroupRespVO.SchoolGroupData> pageResult = new PageResult<>(schoolGroups, (long) totalSchools);
            result.setSchoolGroups(pageResult);
            result.setTotalCount(totalSchools);
            result.setPageNo(pageNo);
            result.setPageSize(pageSize);
            result.setTotalPages((int) Math.ceil((double) totalSchools / pageSize));

            long endTime = System.currentTimeMillis();

            result.setQueryInfo(String.format("查询完成，共找到%d个学校，当前页显示%d个，冲稳保统计：冲刺%d个学校（%d个专业），稳妥%d个学校（%d个专业），保底%d个学校（%d个专业）",
                    totalSchools, schoolGroups.size(),
                    rushSchoolUuids.size(), rushMajors.size(),
                    stableSchoolUuids.size(), stableMajors.size(),
                    safeSchoolUuids.size(), safeMajors.size()));



        return result;
    }

    /**
     * 按专业分组的优化查询方法
     * 优化策略：直接从专业录取数据表获取适合用户的专业数据，然后按专业分组
     */
    private DirectParamsGroupRespVO getMajorGroupedSchoolsOptimized(UserProfileInfo profile,
                                                                   Integer pageNo,
                                                                   Integer pageSize,
                                                                   List<String> levelTypes) {
        long startTime = System.currentTimeMillis();
        log.info("开始按专业分组的优化查询（从专业录取数据表开始），页码：{}，每页：{}，请求等级：{}", pageNo, pageSize, levelTypes);

        DirectParamsGroupRespVO result = new DirectParamsGroupRespVO();
        result.setGroupType("major");

        try {
            // 第一步：直接从专业录取数据表获取适合用户的专业数据
            List<MajorAdmissionDO> admissionData = getFilteredMajorAdmissionData(profile, null);
            if (admissionData.isEmpty()) {
                result.setQueryInfo("未找到符合条件的专业录取数据");
                return result;
            }

            log.info("从专业录取数据表获取到 {} 条专业录取数据", admissionData.size());

            // 第二步：转换为 MajorAdmissionInfo 对象并进行去重
            List<MajorAdmissionInfo> majorInfos = admissionData.stream()
                    .map(this::convertToMajorAdmissionInfo)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());

            // 去重：基于学校UUID、专业名称（去除括号后）、年份进行去重
            Map<String, MajorAdmissionInfo> uniqueMajorsMap = new LinkedHashMap<>();
            for (MajorAdmissionInfo major : majorInfos) {
                String cleanMajorName = removeBrackets(major.getMajorName());
                String uniqueKey = major.getSchoolUUID() + ":" + cleanMajorName + ":" + major.getYear();

                // 如果已存在相同的key，保留专业名称更完整的记录（通常是更长的名称）
                if (uniqueMajorsMap.containsKey(uniqueKey)) {
                    MajorAdmissionInfo existing = uniqueMajorsMap.get(uniqueKey);
                    if (major.getMajorName().length() > existing.getMajorName().length()) {
                        uniqueMajorsMap.put(uniqueKey, major);
                        log.debug("去重：替换专业 {} - {}，原名称：{}，新名称：{}",
                                major.getSchoolName(), cleanMajorName, existing.getMajorName(), major.getMajorName());
                    } else {
                        log.debug("去重：保留专业 {} - {}，保留名称：{}，跳过名称：{}",
                                major.getSchoolName(), cleanMajorName, existing.getMajorName(), major.getMajorName());
                    }
                } else {
                    uniqueMajorsMap.put(uniqueKey, major);
                }
            }

            majorInfos = new ArrayList<>(uniqueMajorsMap.values());
            log.info("专业数据去重完成，原始数量：{}，去重后数量：{}", admissionData.size(), majorInfos.size());

            // 按冲稳保分类（使用动态±10分区间，与按学校分组保持一致）
            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByRushStableSafe(majorInfos, profile.getTotalScore());
            List<MajorAdmissionInfo> rushMajors = classifiedMajors.get("rush");
            List<MajorAdmissionInfo> stableMajors = classifiedMajors.get("stable");
            List<MajorAdmissionInfo> safeMajors = classifiedMajors.get("safe");

            // 统计专业-学校组合数量（按专业分组时不去重，保留所有专业-学校组合）
            int rushMajorSchoolCount = rushMajors.size();
            int stableMajorSchoolCount = stableMajors.size();
            int safeMajorSchoolCount = safeMajors.size();

            // 同时统计去重后的专业名称数量用于对比
            Set<String> rushMajorNames = rushMajors.stream().map(MajorAdmissionInfo::getMajorName).collect(Collectors.toSet());
            Set<String> stableMajorNames = stableMajors.stream().map(MajorAdmissionInfo::getMajorName).collect(Collectors.toSet());
            Set<String> safeMajorNames = safeMajors.stream().map(MajorAdmissionInfo::getMajorName).collect(Collectors.toSet());

            // 统计去括号后的专业数量用于对比
            Set<String> rushMajorNamesWithoutBrackets = rushMajors.stream().map(major -> removeBrackets(major.getMajorName())).collect(Collectors.toSet());
            Set<String> stableMajorNamesWithoutBrackets = stableMajors.stream().map(major -> removeBrackets(major.getMajorName())).collect(Collectors.toSet());
            Set<String> safeMajorNamesWithoutBrackets = safeMajors.stream().map(major -> removeBrackets(major.getMajorName())).collect(Collectors.toSet());

            log.info("冲稳保分类完成 - 冲刺：{}个专业-学校组合（{}个不重复专业，{}个学校），稳妥：{}个专业-学校组合（{}个不重复专业，{}个学校），保底：{}个专业-学校组合（{}个不重复专业，{}个学校）",
                    rushMajorSchoolCount, rushMajorNames.size(), rushMajors.stream().map(MajorAdmissionInfo::getSchoolUUID).collect(Collectors.toSet()).size(),
                    stableMajorSchoolCount, stableMajorNames.size(), stableMajors.stream().map(MajorAdmissionInfo::getSchoolUUID).collect(Collectors.toSet()).size(),
                    safeMajorSchoolCount, safeMajorNames.size(), safeMajors.stream().map(MajorAdmissionInfo::getSchoolUUID).collect(Collectors.toSet()).size());

            log.info("去括号后专业统计 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                    rushMajorNamesWithoutBrackets.size(), stableMajorNamesWithoutBrackets.size(), safeMajorNamesWithoutBrackets.size());

            // 第三步：按专业名称分组（按专业分组的核心逻辑）
            // 分组结果：Key=专业名称，Value=提供该专业的所有学校的录取数据列表
            // 例如："计算机科学与技术" -> [北大的计算机专业数据, 清华的计算机专业数据, 复旦的计算机专业数据, ...]
            // 使用 LinkedHashMap 保证插入顺序，确保分页结果的一致性
            Map<String, List<MajorAdmissionInfo>> majorGroupMap = majorInfos.stream()
                    .collect(Collectors.groupingBy(MajorAdmissionInfo::getMajorName, LinkedHashMap::new, Collectors.toList()));

            // 对专业名称进行排序，确保分页结果的一致性和稳定性
            List<String> uniqueMajorNames = new ArrayList<>(majorGroupMap.keySet());
            uniqueMajorNames.sort(String::compareTo); // 按专业名称字典序排序
            log.info("找到 {} 个不重复的专业名称，总共 {} 条专业-学校记录",
                    uniqueMajorNames.size(), majorInfos.size());

            // 统计每个专业对应的学校数量
            for (String majorName : uniqueMajorNames) {
                List<MajorAdmissionInfo> majorSchools = majorGroupMap.get(majorName);
                Set<String> schoolUUIDs = majorSchools.stream()
                        .map(MajorAdmissionInfo::getSchoolUUID)
                        .collect(Collectors.toSet());
                log.debug("专业 {} 包含 {} 个学校：{}", majorName, schoolUUIDs.size(),
                    majorSchools.stream().map(MajorAdmissionInfo::getSchoolName).distinct().limit(5).collect(Collectors.toList()));
            }

            // 同时统计去括号后的专业数量用于对比
            Set<String> uniqueMajorsWithoutBrackets = majorInfos.stream()
                    .map(major -> removeBrackets(major.getMajorName()))
                    .collect(Collectors.toSet());
            log.info("去括号后不重复专业数量：{}", uniqueMajorsWithoutBrackets.size());

            // 第四步：根据levelTypes过滤专业，只保留在请求等级中有学校的专业
            // 处理 levelTypes 参数，默认返回所有等级
            Set<String> requestedLevels = new HashSet<>();
            if (levelTypes == null || levelTypes.isEmpty()) {
                requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            } else {
                requestedLevels.addAll(levelTypes);
            }

            // 过滤专业：只保留在请求等级中有学校的专业
            List<String> filteredMajorNames = new ArrayList<>();
            for (String majorName : uniqueMajorNames) {
                boolean hasRequestedLevelSchools = false;

                // 检查该专业在各等级中是否有学校
                if (requestedLevels.contains("rush")) {
                    long rushCount = rushMajors.stream()
                            .filter(major -> majorName.equals(major.getMajorName()))
                            .count();
                    if (rushCount > 0) {
                        hasRequestedLevelSchools = true;
                    }
                }

                if (requestedLevels.contains("stable")) {
                    long stableCount = stableMajors.stream()
                            .filter(major -> majorName.equals(major.getMajorName()))
                            .count();
                    if (stableCount > 0) {
                        hasRequestedLevelSchools = true;
                    }
                }

                if (requestedLevels.contains("safe")) {
                    long safeCount = safeMajors.stream()
                            .filter(major -> majorName.equals(major.getMajorName()))
                            .count();
                    if (safeCount > 0) {
                        hasRequestedLevelSchools = true;
                    }
                }

                if (hasRequestedLevelSchools) {
                    filteredMajorNames.add(majorName);
                }
            }

            log.info("根据请求等级 {} 过滤专业，原始专业数：{}，过滤后专业数：{}",
                    requestedLevels, uniqueMajorNames.size(), filteredMajorNames.size());

            // 检查是否有符合条件的专业数据
            if (filteredMajorNames.isEmpty()) {
                result.setQueryInfo("在请求的等级中未找到符合条件的专业数据，但其他等级有数据");
                result.setMajorGroups(new PageResult<>(new ArrayList<>(), 0L));
                result.setTotalCount(0);
                result.setPageNo(pageNo);
                result.setPageSize(pageSize);
                result.setTotalPages(0);

                // 设置真实的分类统计数据（显示其他等级的数据量）
                DirectParamsGroupRespVO.MajorClassificationData majorClassification =
                        new DirectParamsGroupRespVO.MajorClassificationData();
                majorClassification.setRushCount(rushMajorSchoolCount);
                majorClassification.setStableCount(stableMajorSchoolCount);
                majorClassification.setSafeCount(safeMajorSchoolCount);
                majorClassification.setTotalCount(rushMajorSchoolCount + stableMajorSchoolCount + safeMajorSchoolCount);

                // 不设置专业列表，避免性能问题
                majorClassification.setRushMajors(new ArrayList<>());
                majorClassification.setStableMajors(new ArrayList<>());
                majorClassification.setSafeMajors(new ArrayList<>());
                result.setMajorClassification(majorClassification);

                log.info("请求的等级 {} 中没有专业数据，但系统中存在其他等级数据：冲刺{}个专业-学校组合，稳妥{}个专业-学校组合，保底{}个专业-学校组合",
                        requestedLevels, rushMajorSchoolCount, stableMajorSchoolCount, safeMajorSchoolCount);

                return result;
            }

            // 第五步：分页处理过滤后的专业
            // 对过滤后的专业名称再次排序，确保分页结果的一致性
            List<String> majorNames = new ArrayList<>(filteredMajorNames);
            majorNames.sort(String::compareTo); // 按专业名称字典序排序，确保每次查询结果顺序一致

            int totalMajors = majorNames.size();
            int start = (pageNo - 1) * pageSize;
            int end = Math.min(start + pageSize, totalMajors);

            log.info("分页处理前排序：总专业数 {}，页码 {}，每页 {}，起始位置 {}，结束位置 {}",
                    totalMajors, pageNo, pageSize, start, end);

            if (start >= totalMajors) {
                result.setQueryInfo("页码超出范围，请求的等级中共有 " + totalMajors + " 个专业，但请求的页码超出范围");
                return result;
            }

            List<String> pagedMajorNames = majorNames.subList(start, end);
            log.info("分页处理：总专业数 {}，当前页处理 {} 个专业，专业列表：{}",
                    totalMajors, pagedMajorNames.size(),
                    pagedMajorNames.size() <= 5 ? pagedMajorNames : pagedMajorNames.subList(0, 5) + "...");

            // 详细调试日志：显示完整的分页专业名称列表
            log.info("【分页调试】第{}页专业名称完整列表：{}", pageNo, pagedMajorNames);

            // 第六步：批量查询招生计划数据（避免重复查询）
            log.info("开始批量查询当前页专业的招生计划数据");

            // 收集当前页所有专业对应的学校数据（利用已分组的数据，避免重复过滤）
            List<MajorAdmissionInfo> currentPageMajorSchools = new ArrayList<>();
            for (String majorName : pagedMajorNames) {
                List<MajorAdmissionInfo> majorSchools = majorGroupMap.get(majorName);
                if (majorSchools != null) {
                    currentPageMajorSchools.addAll(majorSchools);
                }
            }

            log.info("当前页专业对应的学校数据总数: {}", currentPageMajorSchools.size());

            // 批量查询招生计划数据
            if (!currentPageMajorSchools.isEmpty()) {
                batchQueryLatestYearEnrollmentPlansV2(currentPageMajorSchools, profile);
            }

            // 第七步：为当前页的专业构建分组数据（基于已分类的专业数据）
            List<DirectParamsGroupRespVO.MajorGroupData> majorGroups = new ArrayList<>();
            log.info("开始为当前页的 {} 个专业构建分组数据", pagedMajorNames.size());

            for (int i = 0; i < pagedMajorNames.size(); i++) {
                String majorName = pagedMajorNames.get(i);
                log.debug("处理第 {} 个专业: {}", i + 1, majorName);

                DirectParamsGroupRespVO.MajorGroupData majorGroup = buildMajorGroupDataFromClassifiedMajorsWithoutEnrollmentQuery(
                        majorName, majorInfos, rushMajors, stableMajors, safeMajors, levelTypes);
                if (majorGroup != null && majorGroup.getTotalCount() > 0) {
                    majorGroups.add(majorGroup);
                    log.debug("专业 {} 构建成功，总数: {}", majorName, majorGroup.getTotalCount());
                } else {
                    log.debug("专业 {} 构建失败或总数为0", majorName);
                }
            }

            log.info("完成专业分组数据构建，成功构建 {} 个专业分组", majorGroups.size());

            // 第八步：构建冲稳保分类统计数据（只计算统计数量，不返回完整专业列表以提升性能）
            DirectParamsGroupRespVO.MajorClassificationData majorClassification =
                    new DirectParamsGroupRespVO.MajorClassificationData();

            // 设置统计数量（按专业分组时使用专业-学校组合数量，不去重）
            majorClassification.setRushCount(rushMajorSchoolCount);
            majorClassification.setStableCount(stableMajorSchoolCount);
            majorClassification.setSafeCount(safeMajorSchoolCount);
            majorClassification.setTotalCount(rushMajorSchoolCount + stableMajorSchoolCount + safeMajorSchoolCount);

            // 不设置专业列表，避免性能问题（如果需要完整列表，可以通过其他接口获取）
            majorClassification.setRushMajors(new ArrayList<>());
            majorClassification.setStableMajors(new ArrayList<>());
            majorClassification.setSafeMajors(new ArrayList<>());

            result.setMajorClassification(majorClassification);

            // 第九步：构建返回结果
            PageResult<DirectParamsGroupRespVO.MajorGroupData> pageResult = new PageResult<>(majorGroups, (long) totalMajors);
            result.setMajorGroups(pageResult);
            result.setTotalCount(totalMajors);
            result.setPageNo(pageNo);
            result.setPageSize(pageSize);
            result.setTotalPages((int) Math.ceil((double) totalMajors / pageSize));

            // 详细调试日志：显示最终返回的专业数据
            List<String> returnedMajorNames = majorGroups.stream()
                    .map(DirectParamsGroupRespVO.MajorGroupData::getMajorName)
                    .collect(Collectors.toList());
            log.info("【分页调试】第{}页最终返回的专业名称：{}", pageNo, returnedMajorNames);

            long endTime = System.currentTimeMillis();
            log.info("按专业分组优化查询完成（基于专业录取数据），耗时：{}ms，返回 {} 个专业", endTime - startTime, majorGroups.size());

            result.setQueryInfo(String.format("查询完成，共找到%d个专业（完整名称），当前页显示%d个，冲稳保统计：冲刺%d个专业-学校组合（%d个不重复专业，%d个学校），稳妥%d个专业-学校组合（%d个不重复专业，%d个学校），保底%d个专业-学校组合（%d个不重复专业，%d个学校）。去括号后统计：冲刺%d个，稳妥%d个，保底%d个",
                    totalMajors, majorGroups.size(),
                    rushMajorSchoolCount, rushMajorNames.size(), rushMajors.stream().map(MajorAdmissionInfo::getSchoolUUID).collect(Collectors.toSet()).size(),
                    stableMajorSchoolCount, stableMajorNames.size(), stableMajors.stream().map(MajorAdmissionInfo::getSchoolUUID).collect(Collectors.toSet()).size(),
                    safeMajorSchoolCount, safeMajorNames.size(), safeMajors.stream().map(MajorAdmissionInfo::getSchoolUUID).collect(Collectors.toSet()).size(),
                    rushMajorNamesWithoutBrackets.size(), stableMajorNamesWithoutBrackets.size(), safeMajorNamesWithoutBrackets.size()));

        } catch (Exception e) {
            log.error("按专业分组优化查询失败", e);
            result.setQueryInfo("查询过程中发生错误：" + e.getMessage());
        }

        return result;
    }

    /**
     * 第一步：直接从专业录取数据表获取适合用户的专业数据
     * 优化策略：利用专业录取数据表中的分数字段直接进行筛选和分类
     */
    private List<MajorAdmissionDO> getFilteredMajorAdmissionData(UserProfileInfo profile, String targetSchoolUuid) {
        try {
            String provinceName = profile.getProvince();
            String typeName = profile.getTypeName();
            Integer year = 2024; // 只查询最新一年
            List<String> subjects = profile.getSubjects();
            List<String> interestedMajors = profile.getInterestedMajorCategories();

            // 根据用户选科确定 typeName（如果尚未设置）
            if (typeName == null || typeName.trim().isEmpty()) {
                if (subjects != null && !subjects.isEmpty()) {
                    // 检查是否包含物理和历史，这两个是首选科目
                    boolean hasPhysics = subjects.stream().anyMatch(s -> s.contains("物理"));
                    boolean hasHistory = subjects.stream().anyMatch(s -> s.contains("历史"));

                    String firstSubject = null;
                    if (hasPhysics) {
                        firstSubject = "物理";
                    } else if (hasHistory) {
                        firstSubject = "历史";
                    }

                    if (firstSubject != null) {
                        typeName = determineSubjectSelection(provinceName, firstSubject);
                        profile.setTypeName(typeName); // 更新 profile 中的 typeName
                        log.info("根据用户选科确定查询类型为: {} (省份: {}, 首选科目: {})",
                                typeName, provinceName, firstSubject);
                    }
                }
            }

            log.info("开始从专业录取数据表获取数据 - 省份：{}，类型：{}，年份：{}",
                    provinceName, typeName, year);

            // 获取分数区间（优先使用用户自定义，否则使用与分类逻辑一致的默认值）
            int minScore;
            int maxScore;

            if (profile.getMinScore() != null) {
                minScore = profile.getMinScore();
                log.info("使用用户自定义最低分数: {}", minScore);
            } else {
                // 默认值：保底分数下限（用户分数-20以下），为了包含更多保底专业，扩展到-60
                minScore = profile.getTotalScore() - 60;
                log.info("使用默认最低分数: {} (用户分数-60，包含保底专业)", minScore);
            }

            if (profile.getMaxScore() != null) {
                maxScore = profile.getMaxScore();
                log.info("使用用户自定义最高分数: {}", maxScore);
            } else {
                // 默认值：冲刺分数上限（用户分数+30），与分类逻辑保持一致
                maxScore = profile.getTotalScore() + 30;
                log.info("使用默认最高分数: {} (用户分数+30，包含冲刺专业)", maxScore);
            }

            log.info("查询参数确定 - 省份：{}，类型：{}，年份：{}，分数区间：{}-{}",
                    provinceName, typeName, year, minScore, maxScore);

            // 基础查询条件：省份、年份、分数区间，类型可选
            List<MajorAdmissionDO> admissionData;

            if (targetSchoolUuid != null) {
                // 如果指定了学校UUID，使用批量查询方法（注意：这个方法可能不支持分数区间，需要后续过滤）
                admissionData = majorAdmissionService.batchQueryAdmissionScores(
                        Arrays.asList(targetSchoolUuid), // 学校UUID限制
                        new ArrayList<>(), // 不限制专业名称
                        year,
                        typeName, // 可以为null
                        provinceName
                );

                // 对批量查询结果进行分数过滤
                admissionData = filterAdmissionDataByScoreRange(admissionData, minScore, maxScore);
                log.info("指定学校查询并分数过滤后得到 {} 条专业录取数据", admissionData.size());
            } else {
                // 如果没有指定学校UUID，直接使用省份+年份+类型+分数区间查询所有数据
                admissionData = getAdmissionDataByProvinceYearTypeAndScore(provinceName, year, typeName, minScore, maxScore);
                log.info("基础查询（省份+年份{}+分数区间）得到 {} 条专业录取数据",
                        typeName != null ? "+类型" : "", admissionData.size());

                // 添加数据量检查和警告
                if (admissionData.size() > MAX_DATA_WARNING_THRESHOLD) {
                    log.warn("查询到的专业录取数据量过大（{}条），可能影响系统性能，建议优化查询条件", admissionData.size());
                }
            }

            if (admissionData.isEmpty()) {
                return admissionData;
            }

            // 新增：按专业组扩展结果。如果同校某个专业达到分数条件，则将该校该专业组下的所有专业一并返回（即便它们不在分数区间内）。
            try {
                admissionData = expandAdmissionDataBySpecialGroup(admissionData, provinceName, year, typeName);
            } catch (Exception e) {
                log.warn("按专业组扩展时发生错误，将继续使用未扩展的数据：{}", e.getMessage());
            }

            // 过滤意向专业
            if (interestedMajors != null && !interestedMajors.isEmpty()) {
                admissionData = filterMajorAdmissionByInterestedMajors(admissionData, interestedMajors);
                log.info("意向专业筛选后剩余 {} 条专业录取数据", admissionData.size());
            }

            // 应用新增的筛选条件（学校名称、院校特色、办学性质、大学类型）
            admissionData = applyAdditionalFiltersToAdmissionData(admissionData, profile);

            // 过滤掉专业名称包含"试验班"的专业
//            admissionData = filterOutExperimentalClassMajors(admissionData);

            // 过滤掉batchName包含"国家专项"或"本科提前批"的专业
            admissionData = filterOutSpecialBatchMajors(admissionData);

            return admissionData;

        } catch (Exception e) {
            log.error("从专业录取数据表获取数据失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取过滤后的招生计划数据（优化版本，只查询最新一年）
     */
    private List<CollegeEnrollmentPlanDO> getFilteredEnrollmentPlansOptimized(UserProfileInfo profile) {
        try {
            String provinceName = profile.getProvince();
            Integer year = 2024; // 只查询最新一年
            List<String> subjects = profile.getSubjects();
            List<String> interestedMajors = profile.getInterestedMajorCategories();
            String typeName = profile.getTypeName();
            // 基础查询条件：省份和年份
            List<CollegeEnrollmentPlanDO> enrollmentPlans = collegeEnrollmentPlanMapper
                    .selectListByProvinceAndYearAndType(provinceName, year,typeName);

            log.info("基础查询（省份+年份）得到 {} 条招生计划数据", enrollmentPlans.size());

            if (enrollmentPlans.isEmpty()) {
                return enrollmentPlans;
            }

            // 过滤选科要求
            if (subjects != null && !subjects.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansBySubjects(enrollmentPlans, subjects);
                log.info("选科筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            // 过滤意向专业
            if (interestedMajors != null && !interestedMajors.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansByInterestedMajors(enrollmentPlans, interestedMajors);
                log.info("意向专业筛选后剩余 {} 条招生计划数据", enrollmentPlans.size());
            }

            return enrollmentPlans;

        } catch (Exception e) {
            log.error("获取过滤后的招生计划数据失败", e);
            return new ArrayList<>();
        }
    }



    /**
     * 从2025年招生计划中获取新增专业（没有2024年录取数据的专业）
     * @param existingMajorInfos 已有的专业录取信息列表
     * @param profile 用户档案信息
     * @param targetSchoolUuid 目标学校UUID（可选）
     * @return 新增专业的MajorAdmissionInfo列表
     */
    private List<MajorAdmissionInfo> getNewMajorsFromEnrollmentPlan(List<MajorAdmissionInfo> existingMajorInfos, 
                                                                    UserProfileInfo profile, 
                                                                    String targetSchoolUuid) {
        try {
            String provinceName = profile.getProvince();
            String typeName = profile.getTypeName();
            Integer enrollmentYear = 2025; // 查询2025年招生计划
            List<String> subjects = profile.getSubjects();

            log.info("开始查询2025年招生计划以获取新增专业 - 省份：{}，类型：{}", provinceName, typeName);

            // 1. 收集已有专业的学校和专业组信息
            Set<String> existingSchoolSpecialGroups = new HashSet<>();
            Set<String> existingCombinations = new HashSet<>();
            
            for (MajorAdmissionInfo major : existingMajorInfos) {
                String schoolName = major.getSchoolName();
                String majorName = major.getMajorName();
                String subjectGroup = major.getSubjectGroup(); // 专业组信息

                // 构建已有的学校-专业组合
                existingCombinations.add(buildSchoolMajorKey(schoolName, majorName, subjectGroup));
                
                // 收集已有的学校-专业组组合（用于筛选相同专业组的新增专业）
                if (schoolName != null && subjectGroup != null && !subjectGroup.trim().isEmpty()) {
                    existingSchoolSpecialGroups.add(schoolName + "::" + subjectGroup);
                }
            }
            
            if (existingSchoolSpecialGroups.isEmpty()) {
                log.info("已有专业中未找到有效的专业组信息，跳过新增专业补充");
                return new ArrayList<>();
            }
            
            log.info("收集到{}个学校-专业组组合，用于筛选相同专业组的新增专业", existingSchoolSpecialGroups.size());

            // 2. 从第一步查询结果中提取学校信息，只查询这些学校的2025年招生计划数据
            Set<String> existingSchoolNames = existingMajorInfos.stream()
                    .map(MajorAdmissionInfo::getSchoolName)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            Set<String> existingSchoolUuids = existingMajorInfos.stream()
                    .map(MajorAdmissionInfo::getSchoolUUID)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            log.info("从第一步查询结果中提取到{}个学校名称，{}个学校UUID，只在这些学校中查找新增专业", 
                    existingSchoolNames.size(), existingSchoolUuids.size());
            
            List<CollegeEnrollmentPlanDO> enrollmentPlans;
            if (targetSchoolUuid != null) {
                // 如果指定了学校，只查询该学校的招生计划
                enrollmentPlans = collegeEnrollmentPlanMapper.selectList(
                    new LambdaQueryWrapperX<CollegeEnrollmentPlanDO>()
                        .eq(CollegeEnrollmentPlanDO::getProvinceName, provinceName)
                        .eq(CollegeEnrollmentPlanDO::getYear, enrollmentYear)
                        .eq(CollegeEnrollmentPlanDO::getSchoolUuid, targetSchoolUuid)
                        .notLike(CollegeEnrollmentPlanDO::getBatchName, "国家专项计划")
                        .notLike(CollegeEnrollmentPlanDO::getBatchName, "提前批")
                );
            } else {
                // 只查询第一步结果中出现的学校的招生计划数据
                if (existingSchoolNames.isEmpty()) {
                    log.info("第一步查询结果中没有有效的学校信息，跳过新增专业补充");
                    return new ArrayList<>();
                }
                
                enrollmentPlans = collegeEnrollmentPlanMapper.selectList(
                    new LambdaQueryWrapperX<CollegeEnrollmentPlanDO>()
                        .eq(CollegeEnrollmentPlanDO::getProvinceName, provinceName)
                        .eq(CollegeEnrollmentPlanDO::getYear, enrollmentYear)
                        .in(CollegeEnrollmentPlanDO::getSchoolName, existingSchoolNames)
                        .eq(typeName != null, CollegeEnrollmentPlanDO::getType, typeName)
                        .notLike(CollegeEnrollmentPlanDO::getBatchName, "国家专项计划")
                        .notLike(CollegeEnrollmentPlanDO::getBatchName, "提前批")
                );
            }

            if (enrollmentPlans.isEmpty()) {
                log.info("未找到2025年招生计划数据");
                return new ArrayList<>();
            }

            // 3. 过滤选科要求
            if (subjects != null && !subjects.isEmpty()) {
                enrollmentPlans = filterEnrollmentPlansBySubjects(enrollmentPlans, subjects);
            }

            // 4. 过滤类型
            if (typeName != null && !typeName.trim().isEmpty()) {
                enrollmentPlans = enrollmentPlans.stream()
                        .filter(plan -> typeName.equals(plan.getType()))
                        .collect(Collectors.toList());
            }

            // 5. 只保留与已有专业相同专业组的招生计划
//            enrollmentPlans = enrollmentPlans.stream()
//                    .filter(plan -> {
//                        String schoolName = plan.getSchoolName();
//                        String specialGroupName = plan.getSpecialGroupName();
//
//                        if (schoolName == null || specialGroupName == null || specialGroupName.trim().isEmpty()) {
//                            return false;
//                        }
//
//                        // 检查是否与已有专业的专业组匹配
//                        return isSpecialGroupMatched(schoolName, specialGroupName, existingSchoolSpecialGroups);
//                    })
//                    .collect(Collectors.toList());
            
            log.info("筛选相同专业组后，剩余{}条招生计划", enrollmentPlans.size());

            // 6. 找出招生计划中不在录取数据中的新增专业，直接构建MajorAdmissionInfo
            List<MajorAdmissionInfo> newMajors = new ArrayList<>();
            Set<String> addedCombinations = new HashSet<>();

            for (CollegeEnrollmentPlanDO plan : enrollmentPlans) {
                String schoolName = plan.getSchoolName();
                String majorName = plan.getCollegeMajorName();
                String planKey = buildSchoolMajorKey(schoolName, majorName,plan.getSpecialGroupName());

                // 检查是否为新增专业（不在已有录取数据中）
                if (!existingCombinations.contains(planKey) && !addedCombinations.contains(planKey)) {
                    // 直接从招生计划构建MajorAdmissionInfo对象
                    MajorAdmissionInfo newMajor = createMajorAdmissionInfoFromEnrollmentPlan(plan);
                    if (newMajor != null) {
                        newMajors.add(newMajor);
                        addedCombinations.add(planKey);
                        log.debug("添加相同专业组的新增专业：{} - {}，专业组：{}", 
                                schoolName, majorName, plan.getSpecialGroup());
                    }
                }
            }
            
            log.info("基于相同专业组筛选，最终补充{}个新增专业", newMajors.size());
            return newMajors;

        } catch (Exception e) {
            log.error("从招生计划获取新增专业失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 检查专业组是否匹配
     * 处理MajorAdmissionInfo中的subjectGroup格式（如"1093（W003）"）与
     * CollegeEnrollmentPlan中的specialGroupName格式（如"（003）"）的差异
     * 
     * @param schoolName 学校名称
     * @param specialGroupName 招生计划中的专业组名称（如"（003）"）
     * @param existingSchoolSpecialGroups 已有专业的学校-专业组组合集合
     * @return 是否匹配
     */
    private boolean isSpecialGroupMatched(String schoolName, String specialGroupName, Set<String> existingSchoolSpecialGroups) {
        if (schoolName == null || specialGroupName == null || existingSchoolSpecialGroups.isEmpty()) {
            return false;
        }
        
        // 1. 直接匹配：检查完整的学校-专业组组合
        String directKey = schoolName + "::" + specialGroupName;
        if (existingSchoolSpecialGroups.contains(directKey)) {
            log.debug("专业组直接匹配成功: {}", directKey);
            return true;
        }
        
        // 2. 提取专业组编号进行匹配
        String extractedGroupCode = extractSpecialGroupCode(specialGroupName);
        if (extractedGroupCode != null) {
            // 遍历已有的专业组，查找匹配的编号
            for (String existingKey : existingSchoolSpecialGroups) {
                if (existingKey.startsWith(schoolName + "::")) {
                    String existingSubjectGroup = existingKey.substring((schoolName + "::").length());
                    String existingGroupCode = extractSpecialGroupCode(existingSubjectGroup);
                    
                    if (isGroupCodeMatched(extractedGroupCode, existingGroupCode)) {
                        log.debug("专业组编号匹配成功: {} <-> {}, 提取编号: {} <-> {}", 
                                specialGroupName, existingSubjectGroup, extractedGroupCode, existingGroupCode);
                        return true;
                    }
                }
            }
        }
        
        log.debug("专业组匹配失败: 学校={}, 专业组={}, 提取编号={}", 
                schoolName, specialGroupName, extractedGroupCode);
        return false;
    }
    
    /**
     * 从专业组字符串中提取专业组编号
     * 支持多种格式：
     * - "（003）" -> "003"
     * - "1093（W003）" -> "003" 或 "W003"
     * - "(003)" -> "003"
     * - "W003" -> "W003"
     * 
     * @param specialGroup 专业组字符串
     * @return 提取的专业组编号，如果无法提取则返回null
     */
    private String extractSpecialGroupCode(String specialGroup) {
        if (specialGroup == null || specialGroup.trim().isEmpty()) {
            return null;
        }
        
        String trimmed = specialGroup.trim();
        
        // 1. 提取中文括号内的内容：（003）或（W003）
        Pattern chineseParenPattern = Pattern.compile("（([^）]+)）");
        Matcher chineseMatcher = chineseParenPattern.matcher(trimmed);
        if (chineseMatcher.find()) {
            String content = chineseMatcher.group(1);
            // 如果内容以字母开头（如W003），直接返回
            if (content.matches("[A-Za-z]\\d+")) {
                return content;
            }
            // 如果是纯数字（如003），返回数字部分
            if (content.matches("\\d+")) {
                return content;
            }
            return content;
        }
        
        // 2. 提取英文括号内的内容：(003)或(W003)
        Pattern englishParenPattern = Pattern.compile("\\(([^)]+)\\)");
        Matcher englishMatcher = englishParenPattern.matcher(trimmed);
        if (englishMatcher.find()) {
            String content = englishMatcher.group(1);
            if (content.matches("[A-Za-z]\\d+")) {
                return content;
            }
            if (content.matches("\\d+")) {
                return content;
            }
            return content;
        }
        
        // 3. 如果是字母+数字格式（如W003），直接返回
        if (trimmed.matches("[A-Za-z]\\d+")) {
            return trimmed;
        }
        
        // 4. 如果是纯数字格式（如003），直接返回
        if (trimmed.matches("\\d+")) {
            return trimmed;
        }
        
        // 5. 如果包含数字，尝试提取最后的数字部分
        Pattern numberPattern = Pattern.compile("([A-Za-z]?\\d+)$");
        Matcher numberMatcher = numberPattern.matcher(trimmed);
        if (numberMatcher.find()) {
            return numberMatcher.group(1);
        }
        
        log.debug("无法从专业组字符串中提取编号: {}", specialGroup);
        return null;
    }
    
    /**
     * 检查两个专业组编号是否匹配
     * 支持以下匹配规则：
     * 1. 完全相同："003" == "003", "W003" == "W003"
     * 2. 数字部分相同："005" 匹配 "W005", "L005" 匹配 "005"
     * 
     * @param code1 第一个专业组编号
     * @param code2 第二个专业组编号
     * @return 是否匹配
     */
    private boolean isGroupCodeMatched(String code1, String code2) {
        if (code1 == null || code2 == null) {
            return false;
        }
        
        // 1. 完全相同
        if (code1.equals(code2)) {
            return true;
        }
        
        // 2. 提取数字部分进行比较
        String number1 = extractNumberPart(code1);
        String number2 = extractNumberPart(code2);
        
        if (number1 != null && number2 != null && number1.equals(number2)) {
            log.debug("专业组数字部分匹配: {} ({}) <-> {} ({})", code1, number1, code2, number2);
            return true;
        }
        
        return false;
    }
    
    /**
     * 从专业组编号中提取数字部分
     * 例如："W005" -> "005", "003" -> "003", "L123" -> "123"
     * 
     * @param code 专业组编号
     * @return 数字部分，如果无法提取则返回null
     */
    private String extractNumberPart(String code) {
        if (code == null || code.trim().isEmpty()) {
            return null;
        }
        
        String trimmed = code.trim();
        
        // 如果是纯数字，直接返回
        if (trimmed.matches("\\d+")) {
            return trimmed;
        }
        
        // 如果是字母+数字格式，提取数字部分
        Pattern pattern = Pattern.compile("[A-Za-z]*(\\d+)");
        Matcher matcher = pattern.matcher(trimmed);
        if (matcher.find()) {
            return matcher.group(1);
        }
        
        return null;
    }

    /**
     * 构建学校-专业组合的唯一键
     */
    private String buildSchoolMajorKey(String schoolName, String majorName,String subjectGroup) {
        if (schoolName == null || majorName == null) {
            return "";
        }
        // 去除专业名称中的括号内容，确保匹配的一致性
        String cleanMajorName = removeBrackets(majorName);
        return schoolName + "::" + cleanMajorName+"::"+subjectGroup;
    }

    /**
     * 从招生计划直接创建MajorAdmissionInfo对象（不创建虚拟录取数据）
     */
    private MajorAdmissionInfo createMajorAdmissionInfoFromEnrollmentPlan(CollegeEnrollmentPlanDO plan) {
        try {
            MajorAdmissionInfo majorInfo = new MajorAdmissionInfo();
            
            // 基本信息
            majorInfo.setProvinceName(plan.getProvinceName());
            majorInfo.setSchoolUUID(plan.getSchoolUuid());
            majorInfo.setSchoolName(plan.getSchoolName());
            majorInfo.setMajorName(plan.getCollegeMajorName());
            majorInfo.setMajorCode(plan.getCollegeMajorCode());
            majorInfo.setYear(2025); // 标记为2025年数据
            majorInfo.setTypeName(plan.getType());
            majorInfo.setBatchName(plan.getBatchName());
            majorInfo.setSubjectSelection(plan.getCourseSelectionRequirements());
            majorInfo.setSubjectGroup(plan.getSpecialGroupName());
            
            // 录取分数信息：新增专业没有历史录取数据，设置为null或空字符串
            majorInfo.setLowestScore(null);
            majorInfo.setAverageScore(null);
            majorInfo.setHighScore(null);
            majorInfo.setLowestSection(null);
            
            // 标记为新增专业
            majorInfo.setProScore("NEW_MAJOR_2025");
            
            // 直接设置招生计划数据
            CollegeEnrollmentPlanInfo planInfo = convertToCollegeEnrollmentPlanInfo(plan);
            majorInfo.setEnrollmentPlanData(Arrays.asList(planInfo));
            
            return majorInfo;
            
        } catch (Exception e) {
            log.warn("从招生计划创建专业信息失败：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 根据省份、年份、类型查询专业录取数据（不限制学校和专业）
     */
    private List<MajorAdmissionDO> getAdmissionDataByProvinceYearType(String provinceName, Integer year, String typeName) {
        try {
            // 使用 Mapper 直接查询，避免 batchQueryAdmissionScores 的空参数限制
            LambdaQueryWrapperX<MajorAdmissionDO> wrapper = new LambdaQueryWrapperX<MajorAdmissionDO>();

            // 添加年份条件（必须）
            if (year != null) {
                wrapper.eq(MajorAdmissionDO::getYear, year);
            }

            // 添加省份条件（必须）
            if (StringUtils.hasText(provinceName)) {
                wrapper.eq(MajorAdmissionDO::getProvinceName, provinceName);
            }

            // 添加类型条件（可选）
            if (StringUtils.hasText(typeName)) {
                wrapper.eq(MajorAdmissionDO::getTypeName, typeName);
            }

            List<MajorAdmissionDO> result = majorAdmissionMapper.selectList(wrapper);
            log.info("直接查询专业录取数据 - 省份：{}，年份：{}，类型：{}，结果数量：{}",
                    provinceName, year, typeName, result.size());

            return result;
        } catch (Exception e) {
            log.error("查询专业录取数据失败 - 省份：{}，年份：{}，类型：{}", provinceName, year, typeName, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据省份、年份、类型和分数区间查询专业录取数据（不限制学校和专业）
     */
    private List<MajorAdmissionDO> getAdmissionDataByProvinceYearTypeAndScore(String provinceName, Integer year, String typeName, Integer minScore, Integer maxScore) {
        try {
            // 使用 Mapper 直接查询，避免 batchQueryAdmissionScores 的空参数限制
            LambdaQueryWrapperX<MajorAdmissionDO> wrapper = new LambdaQueryWrapperX<MajorAdmissionDO>();

            // 添加年份条件（必须）
            if (year != null) {
                wrapper.eq(MajorAdmissionDO::getYear, year);
            }

            // 添加省份条件（必须）
            if (StringUtils.hasText(provinceName)) {
                wrapper.eq(MajorAdmissionDO::getProvinceName, provinceName);
            }

            // 添加类型条件（可选）
            if (StringUtils.hasText(typeName)) {
                wrapper.eq(MajorAdmissionDO::getTypeName, typeName);
            }

            // 添加分数范围条件
            if (minScore != null && maxScore != null) {
                wrapper.apply("CAST(lowest_score AS SIGNED) >= {0}", minScore);
                wrapper.apply("CAST(lowest_score AS SIGNED) <= {0}", maxScore);
            }

//            wrapper.eq(MajorAdmissionDO::getSchoolUuid, "01b2dd97f9662e917e4d6e1fb4e99954");

            List<MajorAdmissionDO> result = majorAdmissionMapper.selectList(wrapper);
            log.info("直接查询专业录取数据（含分数区间）- 省份：{}，年份：{}，类型：{}，分数区间：{}-{}，结果数量：{}",
                    provinceName, year, typeName, minScore, maxScore, result.size());

            return result;
        } catch (Exception e) {
            log.error("查询专业录取数据失败（含分数区间）- 省份：{}，年份：{}，类型：{}，分数区间：{}-{}",
                    provinceName, year, typeName, minScore, maxScore, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据分数区间过滤专业录取数据
     * 优化版本：使用传统循环，避免Stream操作导致的栈溢出
     */
    private List<MajorAdmissionDO> filterAdmissionDataByScoreRange(List<MajorAdmissionDO> admissionData, Integer minScore, Integer maxScore) {
        if (admissionData == null || admissionData.isEmpty() || minScore == null || maxScore == null) {
            return admissionData;
        }

        // 检查数据量，如果过大则分批处理
        if (admissionData.size() > LARGE_DATA_THRESHOLD) {
            log.warn("专业录取数据量过大（{}条），使用分批处理避免StackOverflowError", admissionData.size());
            return filterAdmissionDataByScoreRangeBatch(admissionData, minScore, maxScore);
        }

        List<MajorAdmissionDO> filteredData = new ArrayList<>();

        // 使用传统循环代替Stream操作
        for (MajorAdmissionDO admission : admissionData) {
            try {
                String lowestScore = admission.getLowestScore();
                if (lowestScore != null && !lowestScore.trim().isEmpty()) {
                    int score = Integer.parseInt(lowestScore.trim());
                    if (score >= minScore && score <= maxScore) {
                        filteredData.add(admission);
                    }
                }
            } catch (NumberFormatException e) {
                log.debug("无法解析分数: {}", admission.getLowestScore());
            }
        }

        return filteredData;
    }

    /**
     * 分批处理大量专业录取数据的分数区间过滤
     */
    private List<MajorAdmissionDO> filterAdmissionDataByScoreRangeBatch(List<MajorAdmissionDO> admissionData,
                                                                        Integer minScore, Integer maxScore) {
        List<MajorAdmissionDO> allFilteredData = new ArrayList<>();
        int batchSize = BATCH_SIZE;
        int totalSize = admissionData.size();

        for (int i = 0; i < totalSize; i += batchSize) {
            int endIndex = Math.min(i + batchSize, totalSize);
            List<MajorAdmissionDO> batch = admissionData.subList(i, endIndex);

            try {
                List<MajorAdmissionDO> batchFiltered = filterAdmissionDataByScoreRange(batch, minScore, maxScore);
                allFilteredData.addAll(batchFiltered);
            } catch (Exception e) {
                log.error("处理分数区间过滤第{}批数据时发生错误", (i / batchSize + 1), e);
            }
        }

        return allFilteredData;
    }

    /**
     * 应用新增的筛选条件到专业录取数据
     * 包括：学校名称、院校特色、办学性质、大学类型、期望学校所在地
     */
    private List<MajorAdmissionDO> applyAdditionalFiltersToAdmissionData(List<MajorAdmissionDO> admissionData, UserProfileInfo profile) {
        if (admissionData == null || admissionData.isEmpty()) {
            return admissionData;
        }

        String schoolName = profile.getSchoolName();
        List<String> schoolFeatures = profile.getSchoolFeatures();
        List<String> schoolNature = profile.getSchoolProperties();
        List<String> universityTypes = profile.getSchoolTypes();
        String preferredLocation = profile.getPreferredLocation();

        // 如果没有任何新增的筛选条件，直接返回原数据
        if ((schoolName == null || schoolName.trim().isEmpty()) &&
            (schoolFeatures == null || schoolFeatures.isEmpty()) &&
            (schoolNature == null || schoolNature.isEmpty()) &&
            (universityTypes == null || universityTypes.isEmpty()) &&
            (preferredLocation == null || preferredLocation.trim().isEmpty())) {
            return admissionData;
        }

        log.info("开始应用新增筛选条件 - 学校名称: {}, 院校特色: {}, 办学性质: {}, 大学类型: {}, 期望学校所在地: {}",
                schoolName, schoolFeatures, schoolNature, universityTypes, preferredLocation);

        try {
            // 提取所有学校UUID
            List<String> schoolUuids = admissionData.stream()
                    .map(MajorAdmissionDO::getSchoolUuid)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            if (schoolUuids.isEmpty()) {
                log.warn("专业录取数据中没有有效的学校UUID");
                return admissionData;
            }

            log.info("需要查询学校信息的UUID数量: {}", schoolUuids.size());

            // 查询学校信息
            List<CollegeDO> colleges = collegeMapper.selectBySchoolUuids(schoolUuids);
            log.info("查询到 {} 条学校信息", colleges.size());

            // 筛选符合条件的学校UUID
            Set<String> validSchoolUuids = new HashSet<>();
            for (CollegeDO college : colleges) {
                boolean isValid = true;

                // 检查学校名称
                if (schoolName != null && !schoolName.trim().isEmpty()) {
                    if (!isSchoolNameMatch(college.getCollegeName(), schoolName.trim())) {
                        isValid = false;
                    }
                }

                // 检查院校特色
                if (isValid && schoolFeatures != null && !schoolFeatures.isEmpty()) {
                    if (!isSchoolFeaturesMatch(college, schoolFeatures)) {
                        isValid = false;
                    }
                }

                // 检查办学性质
                if (isValid && schoolNature != null && !schoolNature.isEmpty()) {
                    if (!isSchoolNatureMatch(college, schoolNature)) {
                        isValid = false;
                    }
                }

                // 检查大学类型
                if (isValid && universityTypes != null && !universityTypes.isEmpty()) {
                    if (!isUniversityTypeMatch(college, universityTypes)) {
                        isValid = false;
                    }
                }

                // 检查期望学校所在地
                if (isValid && preferredLocation != null && !preferredLocation.trim().isEmpty()) {
                    if (!isLocationMatch(college, preferredLocation.trim())) {
                        isValid = false;
                    }
                }

                if (isValid) {
                    validSchoolUuids.add(college.getSchoolUuid());
                }
            }

            log.info("符合新增筛选条件的学校数量: {}", validSchoolUuids.size());

            if (validSchoolUuids.isEmpty()) {
                log.warn("没有找到符合新增筛选条件的学校");
                return new ArrayList<>();
            }

            // 过滤专业录取数据，只保留符合条件的学校
            List<MajorAdmissionDO> filteredData = admissionData.stream()
                    .filter(admission -> validSchoolUuids.contains(admission.getSchoolUuid()))
                    .collect(Collectors.toList());

            log.info("新增筛选条件应用完成，原始数量: {}, 过滤后数量: {}", admissionData.size(), filteredData.size());
            return filteredData;

        } catch (Exception e) {
            log.error("应用新增筛选条件时发生错误", e);
            return admissionData; // 发生错误时返回原始数据
        }
    }

    /**
     * 根据意向专业过滤专业录取数据
     * 优化版本：避免嵌套Stream操作，减少栈深度
     */
    private List<MajorAdmissionDO> filterMajorAdmissionByInterestedMajors(List<MajorAdmissionDO> admissionData,
                                                                         List<String> interestedMajors) {
        if (interestedMajors == null || interestedMajors.isEmpty()) {
            return admissionData;
        }

        // 检查数据量，如果过大则分批处理
        if (admissionData.size() > LARGE_DATA_THRESHOLD) {
            log.warn("专业录取数据量过大（{}条），使用分批处理避免StackOverflowError", admissionData.size());
            return filterMajorAdmissionByInterestedMajorsBatch(admissionData, interestedMajors);
        }

        List<MajorAdmissionDO> filteredData = new ArrayList<>();

        // 使用传统循环代替嵌套Stream操作
        for (MajorAdmissionDO admission : admissionData) {
            String majorName = admission.getMajorName();
            if (majorName == null) {
                continue;
            }

            // 检查专业名称是否包含任何意向专业关键词
            boolean matched = false;
            for (String interested : interestedMajors) {
                if (majorName.contains(interested) || interested.contains(majorName)) {
                    matched = true;
                    break;
                }
            }

            if (matched) {
                filteredData.add(admission);
            }
        }

        return filteredData;
    }

    /**
     * 分批处理大量专业录取数据的意向专业过滤
     */
    private List<MajorAdmissionDO> filterMajorAdmissionByInterestedMajorsBatch(List<MajorAdmissionDO> admissionData,
                                                                              List<String> interestedMajors) {
        List<MajorAdmissionDO> allFilteredData = new ArrayList<>();
        int batchSize = BATCH_SIZE;
        int totalSize = admissionData.size();

        for (int i = 0; i < totalSize; i += batchSize) {
            int endIndex = Math.min(i + batchSize, totalSize);
            List<MajorAdmissionDO> batch = admissionData.subList(i, endIndex);

            try {
                List<MajorAdmissionDO> batchFiltered = filterMajorAdmissionByInterestedMajors(batch, interestedMajors);
                allFilteredData.addAll(batchFiltered);
            } catch (Exception e) {
                log.error("处理意向专业过滤第{}批数据时发生错误", (i / batchSize + 1), e);
            }
        }

        return allFilteredData;
    }

    /**
     * 根据选科要求过滤专业录取数据（通过招生计划数据验证）
     * 优化版本：分批处理大量数据，避免StackOverflowError
     */
    private List<MajorAdmissionDO> filterMajorAdmissionBySubjects(List<MajorAdmissionDO> admissionData,
                                                                 List<String> subjects,
                                                                 Integer year,
                                                                 String provinceName) {
        if (subjects == null || subjects.isEmpty()) {
            return admissionData;
        }

        // 检查数据量，如果过大则分批处理
        if (admissionData.size() > LARGE_DATA_THRESHOLD) {
            log.warn("专业录取数据量过大（{}条），使用分批处理避免StackOverflowError", admissionData.size());
            return filterMajorAdmissionBySubjectsBatch(admissionData, subjects, year, provinceName);
        }

        // 获取所有相关的招生计划数据来验证选科要求
        Set<String> schoolNamesSet = new HashSet<>();
        Set<String> majorNamesSet = new HashSet<>();

        // 使用传统循环代替Stream，减少栈深度
        for (MajorAdmissionDO admission : admissionData) {
            if (admission.getSchoolName() != null) {
                schoolNamesSet.add(admission.getSchoolName());
            }
            if (admission.getMajorName() != null) {
                majorNamesSet.add(admission.getMajorName());
            }
        }

        List<String> schoolNames = new ArrayList<>(schoolNamesSet);
        List<String> majorNames = new ArrayList<>(majorNamesSet);

        // 使用优化的查询方法，直接根据学校名称和专业名称列表查询，避免查询所有省份+年份数据
        List<CollegeEnrollmentPlanDO> enrollmentPlans = collegeEnrollmentPlanMapper
                .selectExistingEnrollmentPlansWithBracketHandling(schoolNames, majorNames, provinceName, year);

        // 过滤出符合选科要求的招生计划
        List<CollegeEnrollmentPlanDO> validPlans = filterEnrollmentPlansBySubjects(enrollmentPlans, subjects);

        // 构建有效的学校-专业组合（使用学校名称而不是UUID）
        Set<String> validCombinations = new HashSet<>();
        for (CollegeEnrollmentPlanDO plan : validPlans) {
            String combination = plan.getSchoolName() + ":" + plan.getCollegeMajorName();
            validCombinations.add(combination);
        }

        // 过滤专业录取数据 - 使用传统循环代替Stream
        List<MajorAdmissionDO> filteredData = new ArrayList<>();
        for (MajorAdmissionDO admission : admissionData) {
            String combination = admission.getSchoolName() + ":" + admission.getMajorName();
            if (validCombinations.contains(combination)) {
                filteredData.add(admission);
            }
        }

        return filteredData;
    }

    /**
     * 分批处理大量专业录取数据的选科过滤
     * 避免StackOverflowError
     */
    private List<MajorAdmissionDO> filterMajorAdmissionBySubjectsBatch(List<MajorAdmissionDO> admissionData,
                                                                      List<String> subjects,
                                                                      Integer year,
                                                                      String provinceName) {
        List<MajorAdmissionDO> allFilteredData = new ArrayList<>();
        int batchSize = BATCH_SIZE; // 每批处理数据量
        int totalSize = admissionData.size();

        log.info("开始分批处理专业录取数据选科过滤，总数据量：{}，批次大小：{}", totalSize, batchSize);

        for (int i = 0; i < totalSize; i += batchSize) {
            int endIndex = Math.min(i + batchSize, totalSize);
            List<MajorAdmissionDO> batch = admissionData.subList(i, endIndex);

            log.debug("处理第{}批数据，范围：{}-{}", (i / batchSize + 1), i, endIndex - 1);

            try {
                // 递归调用原方法处理小批量数据
                List<MajorAdmissionDO> batchFiltered = filterMajorAdmissionBySubjects(batch, subjects, year, provinceName);
                allFilteredData.addAll(batchFiltered);

                // 添加短暂延迟，避免过度占用资源
                if (i + batchSize < totalSize) {
                    try {
                        Thread.sleep(10); // 10毫秒延迟
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("处理第{}批数据时发生错误，跳过该批次", (i / batchSize + 1), e);
            }
        }

        log.info("分批处理完成，原始数据：{}条，过滤后：{}条", totalSize, allFilteredData.size());
        return allFilteredData;
    }

    /**
     * 过滤掉专业名称包含"试验班"的专业
     * 优化版本：使用传统循环，避免Stream操作导致的栈溢出
     */
    private List<MajorAdmissionDO> filterOutExperimentalClassMajors(List<MajorAdmissionDO> admissionData) {
        if (admissionData == null || admissionData.isEmpty()) {
            return admissionData;
        }

        // 检查数据量，如果过大则分批处理
        if (admissionData.size() > LARGE_DATA_THRESHOLD) {
            log.warn("专业录取数据量过大（{}条），使用分批处理避免StackOverflowError", admissionData.size());
            return filterOutExperimentalClassMajorsBatch(admissionData);
        }

        List<MajorAdmissionDO> filteredData = new ArrayList<>();
        int filteredCount = 0;

        // 使用传统循环代替Stream操作
        for (MajorAdmissionDO admission : admissionData) {
            String majorName = admission.getMajorName();
            if (majorName == null) {
                continue;
            }

            // 检查专业名称是否包含"试验班"
            if (majorName.contains("试验班")) {
                filteredCount++;
                log.debug("过滤掉试验班专业：{} - {}", admission.getSchoolName(), majorName);
                continue;
            }

            filteredData.add(admission);
        }

        if (filteredCount > 0) {
            log.info("过滤掉 {} 个试验班专业，剩余 {} 条专业录取数据", filteredCount, filteredData.size());
        }

        return filteredData;
    }

    /**
     * 分批处理大量专业录取数据的试验班过滤
     */
    private List<MajorAdmissionDO> filterOutExperimentalClassMajorsBatch(List<MajorAdmissionDO> admissionData) {
        List<MajorAdmissionDO> allFilteredData = new ArrayList<>();
        int batchSize = BATCH_SIZE;
        int totalSize = admissionData.size();

        log.info("开始分批处理专业录取数据试验班过滤，总数据量：{}，批次大小：{}", totalSize, batchSize);

        for (int i = 0; i < totalSize; i += batchSize) {
            int endIndex = Math.min(i + batchSize, totalSize);
            List<MajorAdmissionDO> batch = admissionData.subList(i, endIndex);

            log.debug("处理第{}批数据，范围：{}-{}", (i / batchSize + 1), i, endIndex - 1);

            try {
                // 递归调用原方法处理小批量数据
                List<MajorAdmissionDO> batchFiltered = filterOutExperimentalClassMajors(batch);
                allFilteredData.addAll(batchFiltered);

                // 添加短暂延迟，避免过度占用资源
                if (i + batchSize < totalSize) {
                    try {
                        Thread.sleep(10); // 10毫秒延迟
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("处理第{}批数据时发生错误，跳过该批次", (i / batchSize + 1), e);
            }
        }

        log.info("分批处理完成，原始数据：{}条，过滤后：{}条", totalSize, allFilteredData.size());
        return allFilteredData;
    }

    /**
     * 基于已分类的专业数据构建学校分组数据
     */
    private DirectParamsGroupRespVO.SchoolGroupData buildSchoolGroupDataFromClassifiedMajors(
            String schoolUuid, String schoolName,
            List<MajorAdmissionInfo> allMajors,
            List<MajorAdmissionInfo> rushMajors,
            List<MajorAdmissionInfo> stableMajors,
            List<MajorAdmissionInfo> safeMajors,
            List<String> levelTypes,
            Boolean includeMajorDetails,
            UserProfileInfo profile) {

        try {
            // 处理 levelTypes 参数，默认返回所有等级
            Set<String> requestedLevels = new HashSet<>();
            if (levelTypes == null || levelTypes.isEmpty()) {
                requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            } else {
                requestedLevels.addAll(levelTypes);
            }

            // 筛选出该学校的专业并进行去重
            List<MajorAdmissionInfo> schoolMajors = allMajors.stream()
                    .filter(major -> major != null && major.getSchoolUUID() != null && schoolUuid.equals(major.getSchoolUUID()))
                    .collect(Collectors.toList());

            if (schoolMajors.isEmpty()) {
                return null;
            }

            log.debug("学校 {} 专业去重完成，原始数量：{}，去重后数量：{}",
                     schoolName, allMajors.stream().filter(major -> schoolUuid.equals(major.getSchoolUUID())).count(), schoolMajors.size());

            // 重新统计该学校各等级的专业数量（基于去重后的专业列表）
            List<MajorAdmissionInfo> schoolRushMajors;
            List<MajorAdmissionInfo> schoolStableMajors;
            List<MajorAdmissionInfo> schoolSafeMajors;

            // 为该学校的专业添加近三年招生计划数据
            try {
                log.debug("开始为学校 {} 的 {} 个专业查询近三年招生计划数据",
                         schoolName, schoolMajors.size());

                // 使用现有的优化方法为专业添加招生计划数据
                batchQueryLatestYearEnrollmentPlansV2(schoolMajors, profile);

                log.debug("完成为学校 {} 的专业查询招生计划数据", schoolName);
            } catch (Exception e) {
                log.warn("为学校 {} 查询招生计划数据失败: {}", schoolName, e.getMessage());
            }

            // 为该学校的专业添加近三年历史录取数据
            try {
                log.debug("开始为学校 {} 的 {} 个专业查询近三年历史录取数据",
                         schoolName, schoolMajors.size());

                // 查询近三年历史录取数据
                batchQueryThreeYearsAdmissionScores(schoolMajors,profile);

                log.debug("完成为学校 {} 的专业查询历史录取数据", schoolName);
            } catch (Exception e) {
                log.warn("为学校 {} 查询历史录取数据失败: {}", schoolName, e.getMessage());
            }

            // 第五步：再进行一次过滤，只保留有2025年招生计划的专业
            int originalCount = schoolMajors.size();
            schoolMajors = schoolMajors.stream()
                    .filter(major -> {
                        if (major.getEnrollmentPlanData() == null || major.getEnrollmentPlanData().isEmpty()) {
                            return false;
                        }
                        // 检查是否有2025年的招生计划
                        boolean has2025Plan = major.getEnrollmentPlanData().stream()
                                .anyMatch(plan -> plan.getYear() != null && plan.getYear() == 2025);
                        
                        // 如果是新增专业（标记为NEW_MAJOR_2025），也保留
                        boolean isNewMajor = "NEW_MAJOR_2025".equals(major.getProScore());
                        
                        log.debug("专业 {} - {}：有2025年招生计划={}, 是新增专业={}", 
                                 major.getSchoolName(), major.getMajorName(), has2025Plan, isNewMajor);
                        
                        return has2025Plan || isNewMajor;
                    })
                    .collect(Collectors.toList());

            int filteredCount = originalCount - schoolMajors.size();
            if (filteredCount > 0) {
                log.debug("学校 {} 过滤掉 {} 个没有招生计划数据的专业，剩余 {} 个专业",
                         schoolName, filteredCount, schoolMajors.size());
            }

            // 如果过滤后没有专业了，直接返回null
            if (schoolMajors.isEmpty()) {
                log.debug("学校 {} 过滤后没有专业，返回null", schoolName);
                return null;
            }

            // 重新统计该学校各等级的专业数量（基于去重后且有招生计划的专业列表）
            // 使用去重后的schoolMajors作为基础，而不是原始的分类数据
            schoolRushMajors = schoolMajors.stream()
                    .filter(major -> major.getSchoolUUID() != null && rushMajors.stream().anyMatch(rush ->
                            rush.getSchoolUUID() != null &&
                            rush.getSchoolUUID().equals(major.getSchoolUUID()) &&
                            Objects.equals(rush.getMajorName(), major.getMajorName()) &&
                            Objects.equals(rush.getYear(), major.getYear()) &&
                            Objects.equals(rush.getBatchName(), major.getBatchName()) &&
                            Objects.equals(rush.getTypeName(), major.getTypeName())))
                    .collect(Collectors.toList());

            schoolStableMajors = schoolMajors.stream()
                    .filter(major -> major.getSchoolUUID() != null && stableMajors.stream().anyMatch(stable ->
                            stable.getSchoolUUID() != null &&
                            stable.getSchoolUUID().equals(major.getSchoolUUID()) &&
                            Objects.equals(stable.getMajorName(), major.getMajorName()) &&
                            Objects.equals(stable.getYear(), major.getYear()) &&
                            Objects.equals(stable.getBatchName(), major.getBatchName()) &&
                            Objects.equals(stable.getTypeName(), major.getTypeName())))
                    .collect(Collectors.toList());

            schoolSafeMajors = schoolMajors.stream()
                    .filter(major -> major.getSchoolUUID() != null && safeMajors.stream().anyMatch(safe ->
                            safe.getSchoolUUID() != null &&
                            safe.getSchoolUUID().equals(major.getSchoolUUID()) &&
                            Objects.equals(safe.getMajorName(), major.getMajorName()) &&
                            Objects.equals(safe.getYear(), major.getYear()) &&
                            Objects.equals(safe.getBatchName(), major.getBatchName()) &&
                            Objects.equals(safe.getTypeName(), major.getTypeName())))
                    .collect(Collectors.toList());

            log.debug("学校 {} 各等级专业统计（去重后）：冲刺{}个，稳妥{}个，保底{}个",
                     schoolName, schoolRushMajors.size(), schoolStableMajors.size(), schoolSafeMajors.size());

            // 根据用户请求的等级类型过滤学校：如果学校在请求的等级中没有专业，则不返回该学校
            boolean hasRequestedLevelMajors = false;
            if (requestedLevels.contains("rush") && schoolRushMajors.size() > 0) {
                hasRequestedLevelMajors = true;
            }
            if (requestedLevels.contains("stable") && schoolStableMajors.size() > 0) {
                hasRequestedLevelMajors = true;
            }
            if (requestedLevels.contains("safe") && schoolSafeMajors.size() > 0) {
                hasRequestedLevelMajors = true;
            }

            if (!hasRequestedLevelMajors) {
                log.debug("学校 {} 在请求的等级 {} 中没有专业，跳过", schoolName, requestedLevels);
                return null;
            }

            // 构建学校分组数据
            DirectParamsGroupRespVO.SchoolGroupData schoolGroup = new DirectParamsGroupRespVO.SchoolGroupData();
            schoolGroup.setSchoolName(schoolName);
            schoolGroup.setSchoolUuid(schoolUuid);
            schoolGroup.setRushCount(schoolRushMajors.size());
            schoolGroup.setStableCount(schoolStableMajors.size());
            schoolGroup.setSafeCount(schoolSafeMajors.size());
            schoolGroup.setTotalCount(schoolMajors.size());

            // 确定学校等级
            String schoolLevel;
            if (schoolRushMajors.size() > 0) {
                schoolLevel = "rush";
            } else if (schoolStableMajors.size() > 0) {
                schoolLevel = "stable";
            } else {
                schoolLevel = "safe";
            }
            schoolGroup.setLevelType(schoolLevel);

            // 根据参数决定是否返回专业详情，并且只返回用户请求的等级的专业
            if (includeMajorDetails != null && includeMajorDetails) {
                schoolGroup.setRushMajors(requestedLevels.contains("rush") ?
                    convertToDirectParamsMajorAdmissionInfo(schoolRushMajors) : null);
                schoolGroup.setStableMajors(requestedLevels.contains("stable") ?
                    convertToDirectParamsMajorAdmissionInfo(schoolStableMajors) : null);
                schoolGroup.setSafeMajors(requestedLevels.contains("safe") ?
                    convertToDirectParamsMajorAdmissionInfo(schoolSafeMajors) : null);
                schoolGroup.setHasMajorDetails(true);
            } else {
                schoolGroup.setRushMajors(null);
                schoolGroup.setStableMajors(null);
                schoolGroup.setSafeMajors(null);
                schoolGroup.setHasMajorDetails(false);
            }

            // 统计该校24年所有专业的招生计划人数、录取最低分和最低位次
            try {
                // 统计招生计划人数总和
                int totalEnrollmentPlan = 0;
                String lowestAdmissionScore = null;
                String lowestAdmissionRank = null;

                for (MajorAdmissionInfo major : schoolMajors) {
                    // 统计招生计划人数
                    if (major.getEnrollmentPlanData() != null) {
                        for (CollegeEnrollmentPlanInfo planInfo : major.getEnrollmentPlanData()) {
                            if (planInfo.getYear() != null && planInfo.getYear() == 2024 && planInfo.getEnrollmentNumbers() != null) {
                                totalEnrollmentPlan += parseEnrollmentNumbers(planInfo.getEnrollmentNumbers());
                            }
                        }
                    }

                    // 统计录取最低分（找出所有专业中的最低分）
                    if (major.getLowestScore() != null && !major.getLowestScore().trim().isEmpty()) {
                        try {
                            double currentScore = Double.parseDouble(major.getLowestScore());
                            if (lowestAdmissionScore == null || Double.parseDouble(lowestAdmissionScore) > currentScore) {
                                lowestAdmissionScore = major.getLowestScore();
                            }
                        } catch (NumberFormatException e) {
                            log.debug("专业 {} 的最低分格式不正确: {}", major.getMajorName(), major.getLowestScore());
                        }
                    }

                    // 统计最低位次（找出所有专业中的最低位次，即数值最大的位次）
                    if (major.getLowestSection() != null && !major.getLowestSection().trim().isEmpty()) {
                        try {
                            long currentRank = Long.parseLong(major.getLowestSection());
                            if (lowestAdmissionRank == null || Long.parseLong(lowestAdmissionRank) < currentRank) {
                                lowestAdmissionRank = major.getLowestSection();
                            }
                        } catch (NumberFormatException e) {
                            log.debug("专业 {} 的最低位次格式不正确: {}", major.getMajorName(), major.getLowestSection());
                        }
                    }
                }

                // 设置统计结果
                schoolGroup.setTotalEnrollmentPlan(totalEnrollmentPlan > 0 ? totalEnrollmentPlan : null);
                schoolGroup.setLowestAdmissionScore(lowestAdmissionScore);
                schoolGroup.setLowestAdmissionRank(lowestAdmissionRank);

                log.debug("学校 {} 统计结果：招生计划总数={}，录取最低分={}，最低位次={}",
                         schoolName, totalEnrollmentPlan, lowestAdmissionScore, lowestAdmissionRank);

            } catch (Exception e) {
                log.warn("统计学校 {} 的招生计划和录取数据失败: {}", schoolName, e.getMessage());
            }

            // 获取学校基础信息
            try {
                DirectParamsGroupRespVO.SchoolBasicInfo schoolInfo = getSchoolBasicInfo(schoolUuid);
                schoolGroup.setSchoolInfo(schoolInfo);
            } catch (Exception e) {
                log.warn("获取学校基础信息失败，学校：{}，错误：{}", schoolName, e.getMessage());
            }

            log.debug("学校 {} 符合请求等级 {}，返回数据", schoolName, requestedLevels);
            return schoolGroup;

        } catch (Exception e) {
            log.error("构建学校分组数据失败，学校：{}", schoolName, e);
            return null;
        }
    }

    /**
     * 基于已分类的专业数据构建专业分组数据
     */
    private DirectParamsGroupRespVO.MajorGroupData buildMajorGroupDataFromClassifiedMajors(
            String majorName,
            List<MajorAdmissionInfo> allMajors,
            List<MajorAdmissionInfo> rushMajors,
            List<MajorAdmissionInfo> stableMajors,
            List<MajorAdmissionInfo> safeMajors,
            List<String> levelTypes,
            UserProfileInfo profile) {

        try {
            // 处理 levelTypes 参数，默认返回所有等级
            Set<String> requestedLevels = new HashSet<>();
            if (levelTypes == null || levelTypes.isEmpty()) {
                requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            } else {
                requestedLevels.addAll(levelTypes);
            }

            // 筛选出该专业的学校（使用完整专业名称匹配）并进行去重
            List<MajorAdmissionInfo> majorSchools = allMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            log.debug("专业 {} 匹配到 {} 个学校", majorName, majorSchools.size());

            if (majorSchools.isEmpty()) {
                log.debug("专业 {} 没有匹配到任何学校，返回null", majorName);
                return null;
            }

            // 对该专业的学校进行去重，避免同一学校重复出现
            Map<String, MajorAdmissionInfo> uniqueMajorSchoolsMap = new LinkedHashMap<>();
            for (MajorAdmissionInfo major : majorSchools) {
                String uniqueKey = major.getSchoolUUID() + ":" +
                                 major.getYear() + ":" +
                                 major.getBatchName() + ":" +
                                 major.getTypeName();

                // 如果已存在相同的key，保留学校名称更完整的记录
                if (uniqueMajorSchoolsMap.containsKey(uniqueKey)) {
                    MajorAdmissionInfo existing = uniqueMajorSchoolsMap.get(uniqueKey);
                    if (major.getSchoolName().length() > existing.getSchoolName().length()) {
                        uniqueMajorSchoolsMap.put(uniqueKey, major);
                        log.debug("专业{}去重：替换学校{}，原名称：{}，新名称：{}",
                                majorName, uniqueKey, existing.getSchoolName(), major.getSchoolName());
                    }
                } else {
                    uniqueMajorSchoolsMap.put(uniqueKey, major);
                }
            }

            majorSchools = new ArrayList<>(uniqueMajorSchoolsMap.values());
            log.debug("专业 {} 学校去重完成，原始数量：{}，去重后数量：{}",
                     majorName, allMajors.stream().filter(major -> majorName.equals(major.getMajorName())).count(), majorSchools.size());

            // 统计该专业各等级的学校数量（使用完整专业名称匹配）
            List<MajorAdmissionInfo> majorRushSchools = rushMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            List<MajorAdmissionInfo> majorStableSchools = stableMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            List<MajorAdmissionInfo> majorSafeSchools = safeMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            // 为该专业的学校添加2024年招生计划数据
            try {
                log.debug("开始为专业 {} 的 {} 个学校查询2024年招生计划数据",
                         majorName, majorSchools.size());

                // 使用现有的优化方法为学校添加招生计划数据
                batchQueryLatestYearEnrollmentPlansV2(majorSchools, profile);

                log.debug("完成为专业 {} 的学校查询招生计划数据", majorName);
            } catch (Exception e) {
                log.warn("为专业 {} 查询招生计划数据失败: {}", majorName, e.getMessage());
            }

            // 再进行一次过滤，过滤掉没有招生计划数据的学校
            int originalCount = majorSchools.size();
            majorSchools = majorSchools.stream()
                    .filter(major -> major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty())
                    .collect(Collectors.toList());

            int filteredCount = originalCount - majorSchools.size();
            if (filteredCount > 0) {
                log.debug("专业 {} 过滤掉 {} 个没有招生计划数据的学校，剩余 {} 个学校",
                         majorName, filteredCount, majorSchools.size());
            }

            // 如果过滤后没有学校了，直接返回null
            if (majorSchools.isEmpty()) {
                log.debug("专业 {} 过滤后没有学校，返回null", majorName);
                return null;
            }

            // 重新统计该专业各等级的学校数量（基于过滤后的学校列表）
            majorRushSchools = rushMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .filter(major -> major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty())
                    .collect(Collectors.toList());

            majorStableSchools = stableMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .filter(major -> major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty())
                    .collect(Collectors.toList());

            majorSafeSchools = safeMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .filter(major -> major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty())
                    .collect(Collectors.toList());

            // 根据用户请求的等级类型过滤专业：如果专业在请求的等级中没有学校，则不返回该专业
            boolean hasRequestedLevelSchools = false;
            if (requestedLevels.contains("rush") && majorRushSchools.size() > 0) {
                hasRequestedLevelSchools = true;
            }
            if (requestedLevels.contains("stable") && majorStableSchools.size() > 0) {
                hasRequestedLevelSchools = true;
            }
            if (requestedLevels.contains("safe") && majorSafeSchools.size() > 0) {
                hasRequestedLevelSchools = true;
            }

            if (!hasRequestedLevelSchools) {
                log.debug("专业 {} 在请求的等级 {} 中没有学校，跳过", majorName, requestedLevels);
                return null;
            }

            // 构建专业分组数据
            DirectParamsGroupRespVO.MajorGroupData majorGroup = new DirectParamsGroupRespVO.MajorGroupData();
            majorGroup.setMajorName(majorName);
            majorGroup.setRushCount(majorRushSchools.size());
            majorGroup.setStableCount(majorStableSchools.size());
            majorGroup.setSafeCount(majorSafeSchools.size());
            majorGroup.setTotalCount(majorSchools.size());

            // 确定专业等级
            String majorLevel;
            if (majorRushSchools.size() > 0) {
                majorLevel = "rush";
            } else if (majorStableSchools.size() > 0) {
                majorLevel = "stable";
            } else {
                majorLevel = "safe";
            }
            majorGroup.setLevelType(majorLevel);

            // 根据用户请求的等级类型设置学校详情，只返回用户请求的等级的学校
            majorGroup.setRushSchools(requestedLevels.contains("rush") ?
                convertToDirectParamsMajorAdmissionInfo(majorRushSchools) : null);
            majorGroup.setStableSchools(requestedLevels.contains("stable") ?
                convertToDirectParamsMajorAdmissionInfo(majorStableSchools) : null);
            majorGroup.setSafeSchools(requestedLevels.contains("safe") ?
                convertToDirectParamsMajorAdmissionInfo(majorSafeSchools) : null);

            log.debug("专业 {} 符合请求等级 {}，返回数据", majorName, requestedLevels);
            return majorGroup;

        } catch (Exception e) {
            log.error("构建专业分组数据失败，专业：{}", majorName, e);
            return null;
        }
    }

    /**
     * 基于已分类的专业数据构建专业分组数据（不查询招生计划数据）
     */
    private DirectParamsGroupRespVO.MajorGroupData buildMajorGroupDataFromClassifiedMajorsWithoutEnrollmentQuery(
            String majorName,
            List<MajorAdmissionInfo> allMajors,
            List<MajorAdmissionInfo> rushMajors,
            List<MajorAdmissionInfo> stableMajors,
            List<MajorAdmissionInfo> safeMajors,
            List<String> levelTypes) {

        try {
            // 处理 levelTypes 参数，默认返回所有等级
            Set<String> requestedLevels = new HashSet<>();
            if (levelTypes == null || levelTypes.isEmpty()) {
                requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
            } else {
                requestedLevels.addAll(levelTypes);
            }

            // 筛选出该专业的学校（使用完整专业名称匹配）并进行去重
            List<MajorAdmissionInfo> majorSchools = allMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            log.debug("专业 {} 匹配到 {} 个学校", majorName, majorSchools.size());

            if (majorSchools.isEmpty()) {
                log.debug("专业 {} 没有匹配到任何学校，返回null", majorName);
                return null;
            }

            // 对该专业的学校进行去重，避免同一学校重复出现
            Map<String, MajorAdmissionInfo> uniqueMajorSchoolsMap = new LinkedHashMap<>();
            for (MajorAdmissionInfo major : majorSchools) {
                String uniqueKey = major.getSchoolUUID() + ":" +
                                 major.getYear() + ":" +
                                 major.getBatchName() + ":" +
                                 major.getTypeName();

                // 如果已存在相同的key，保留学校名称更完整的记录
                if (uniqueMajorSchoolsMap.containsKey(uniqueKey)) {
                    MajorAdmissionInfo existing = uniqueMajorSchoolsMap.get(uniqueKey);
                    if (major.getSchoolName().length() > existing.getSchoolName().length()) {
                        uniqueMajorSchoolsMap.put(uniqueKey, major);
                        log.debug("专业{}去重：替换学校{}，原名称：{}，新名称：{}",
                                majorName, uniqueKey, existing.getSchoolName(), major.getSchoolName());
                    }
                } else {
                    uniqueMajorSchoolsMap.put(uniqueKey, major);
                }
            }

            majorSchools = new ArrayList<>(uniqueMajorSchoolsMap.values());
            log.debug("专业 {} 学校去重完成，原始数量：{}，去重后数量：{}",
                     majorName, allMajors.stream().filter(major -> majorName.equals(major.getMajorName())).count(), majorSchools.size());

            // 统计该专业各等级的学校数量（使用完整专业名称匹配）
            List<MajorAdmissionInfo> majorRushSchools = rushMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            List<MajorAdmissionInfo> majorStableSchools = stableMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            List<MajorAdmissionInfo> majorSafeSchools = safeMajors.stream()
                    .filter(major -> majorName.equals(major.getMajorName()))
                    .collect(Collectors.toList());

            // 根据用户请求的等级类型过滤专业：如果专业在请求的等级中没有学校，则不返回该专业
            boolean hasRequestedLevelSchools = false;
            if (requestedLevels.contains("rush") && majorRushSchools.size() > 0) {
                hasRequestedLevelSchools = true;
            }
            if (requestedLevels.contains("stable") && majorStableSchools.size() > 0) {
                hasRequestedLevelSchools = true;
            }
            if (requestedLevels.contains("safe") && majorSafeSchools.size() > 0) {
                hasRequestedLevelSchools = true;
            }

            if (!hasRequestedLevelSchools) {
                log.debug("专业 {} 在请求的等级 {} 中没有学校，跳过", majorName, requestedLevels);
                return null;
            }

            // 构建专业分组数据
            DirectParamsGroupRespVO.MajorGroupData majorGroup = new DirectParamsGroupRespVO.MajorGroupData();
            majorGroup.setMajorName(majorName);
            majorGroup.setRushCount(majorRushSchools.size());
            majorGroup.setStableCount(majorStableSchools.size());
            majorGroup.setSafeCount(majorSafeSchools.size());
            majorGroup.setTotalCount(majorSchools.size());

            // 确定专业等级
            String majorLevel;
            if (majorRushSchools.size() > 0) {
                majorLevel = "rush";
            } else if (majorStableSchools.size() > 0) {
                majorLevel = "stable";
            } else {
                majorLevel = "safe";
            }
            majorGroup.setLevelType(majorLevel);

            // 根据用户请求的等级类型设置学校详情，只返回用户请求的等级的学校
            majorGroup.setRushSchools(requestedLevels.contains("rush") ?
                convertToDirectParamsMajorAdmissionInfo(majorRushSchools) : null);
            majorGroup.setStableSchools(requestedLevels.contains("stable") ?
                convertToDirectParamsMajorAdmissionInfo(majorStableSchools) : null);
            majorGroup.setSafeSchools(requestedLevels.contains("safe") ?
                convertToDirectParamsMajorAdmissionInfo(majorSafeSchools) : null);

            log.debug("专业 {} 符合请求等级 {}，返回数据", majorName, requestedLevels);
            return majorGroup;

        } catch (Exception e) {
            log.error("构建专业分组数据失败，专业：{}", majorName, e);
            return null;
        }
    }

//    /**
//     * 获取单个学校的分组数据（优化版本）
//     */
//    private DirectParamsGroupRespVO.SchoolGroupData getSchoolGroupDataOptimized(String schoolUuid,
//                                                                               String schoolName,
//                                                                               UserProfileInfo profile,
//                                                                               List<String> levelTypes,
//                                                                               Boolean includeMajorDetails) {
//        try {
//            // 查询该学校的专业录取数据（只查询最新一年）
//            List<MajorAdmissionDO> admissionData = majorAdmissionService.batchQueryAdmissionScores(
//                    Arrays.asList(schoolUuid),
//                    new ArrayList<>(), // 不限制专业名称
//                    2024, // 只查询最新一年
//                    profile.getTypeName(),
//                    profile.getProvince()
//            );
//
//            if (admissionData.isEmpty()) {
//                return null;
//            }
//
//            // 转换为 MajorAdmissionInfo 对象
//            List<MajorAdmissionInfo> majorInfos = admissionData.stream()
//                    .map(this::convertToMajorAdmissionInfo)
//                    .filter(Objects::nonNull)
//                    .collect(Collectors.toList());
//
//            // 按冲稳保分类
//            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByScore(majorInfos, profile.getTotalScore());
//
//            List<MajorAdmissionInfo> rushMajors = classifiedMajors.get("rush");
//            List<MajorAdmissionInfo> stableMajors = classifiedMajors.get("stable");
//            List<MajorAdmissionInfo> safeMajors = classifiedMajors.get("safe");
//
//            // 构建学校分组数据
//            DirectParamsGroupRespVO.SchoolGroupData schoolGroup = new DirectParamsGroupRespVO.SchoolGroupData();
//            schoolGroup.setSchoolName(schoolName);
//            schoolGroup.setSchoolUuid(schoolUuid);
//            schoolGroup.setRushCount(rushMajors.size());
//            schoolGroup.setStableCount(stableMajors.size());
//            schoolGroup.setSafeCount(safeMajors.size());
//            schoolGroup.setTotalCount(majorInfos.size());
//
//            // 确定学校等级
//            String schoolLevel;
//            if (rushMajors.size() > 0) {
//                schoolLevel = "rush";
//            } else if (stableMajors.size() > 0) {
//                schoolLevel = "stable";
//            } else {
//                schoolLevel = "safe";
//            }
//            schoolGroup.setLevelType(schoolLevel);
//
//            // 根据参数决定是否返回专业详情
//            if (includeMajorDetails != null && includeMajorDetails) {
//                schoolGroup.setRushMajors(convertToDirectParamsMajorAdmissionInfo(rushMajors));
//                schoolGroup.setStableMajors(convertToDirectParamsMajorAdmissionInfo(stableMajors));
//                schoolGroup.setSafeMajors(convertToDirectParamsMajorAdmissionInfo(safeMajors));
//                schoolGroup.setHasMajorDetails(true);
//            } else {
//                schoolGroup.setRushMajors(null);
//                schoolGroup.setStableMajors(null);
//                schoolGroup.setSafeMajors(null);
//                schoolGroup.setHasMajorDetails(false);
//            }
//
//            // 获取学校基础信息
//            try {
//                DirectParamsGroupRespVO.SchoolBasicInfo schoolInfo = getSchoolBasicInfo(schoolUuid);
//                schoolGroup.setSchoolInfo(schoolInfo);
//            } catch (Exception e) {
//                log.warn("获取学校基础信息失败，学校：{}，错误：{}", schoolName, e.getMessage());
//            }
//
//            return schoolGroup;
//
//        } catch (Exception e) {
//            log.error("获取学校分组数据失败，学校：{}", schoolName, e);
//            return null;
//        }
//    }

    /**
     * 获取单个专业的分组数据（优化版本）
     */
//    private DirectParamsGroupRespVO.MajorGroupData getMajorGroupDataOptimized(String majorName,
//                                                                             UserProfileInfo profile,
//                                                                             List<String> levelTypes) {
//        try {
//            // 处理 levelTypes 参数，默认返回所有等级
//            Set<String> requestedLevels = new HashSet<>();
//            if (levelTypes == null || levelTypes.isEmpty()) {
//                requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
//            } else {
//                requestedLevels.addAll(levelTypes);
//            }
//
//            // 查询该专业的录取数据（只查询最新一年）
//            List<MajorAdmissionDO> admissionData = majorAdmissionService.batchQueryAdmissionScores(
//                    new ArrayList<>(), // 不限制学校
//                    Arrays.asList(majorName),
//                    2024, // 只查询最新一年
//                    profile.getTypeName(),
//                    profile.getProvince()
//            );
//
//            if (admissionData.isEmpty()) {
//                return null;
//            }
//
//            // 转换为 MajorAdmissionInfo 对象
//            List<MajorAdmissionInfo> majorInfos = admissionData.stream()
//                    .map(this::convertToMajorAdmissionInfo)
//                    .filter(Objects::nonNull)
//                    .collect(Collectors.toList());
//
//            // 按冲稳保分类
//            Map<String, List<MajorAdmissionInfo>> classifiedMajors = classifyMajorsByScore(majorInfos, profile.getTotalScore());
//
//            List<MajorAdmissionInfo> rushSchools = classifiedMajors.get("rush");
//            List<MajorAdmissionInfo> stableSchools = classifiedMajors.get("stable");
//            List<MajorAdmissionInfo> safeSchools = classifiedMajors.get("safe");
//
//            // 根据用户请求的等级类型过滤专业：如果专业在请求的等级中没有学校，则不返回该专业
//            boolean hasRequestedLevelSchools = false;
//            if (requestedLevels.contains("rush") && rushSchools.size() > 0) {
//                hasRequestedLevelSchools = true;
//            }
//            if (requestedLevels.contains("stable") && stableSchools.size() > 0) {
//                hasRequestedLevelSchools = true;
//            }
//            if (requestedLevels.contains("safe") && safeSchools.size() > 0) {
//                hasRequestedLevelSchools = true;
//            }
//
//            if (!hasRequestedLevelSchools) {
//                log.debug("专业 {} 在请求的等级 {} 中没有学校，跳过", majorName, requestedLevels);
//                return null;
//            }
//
//            // 构建专业分组数据
//            DirectParamsGroupRespVO.MajorGroupData majorGroup = new DirectParamsGroupRespVO.MajorGroupData();
//            majorGroup.setMajorName(majorName);
//            majorGroup.setRushCount(rushSchools.size());
//            majorGroup.setStableCount(stableSchools.size());
//            majorGroup.setSafeCount(safeSchools.size());
//            majorGroup.setTotalCount(majorInfos.size());
//
//            // 确定专业等级
//            String majorLevel;
//            if (rushSchools.size() > 0) {
//                majorLevel = "rush";
//            } else if (stableSchools.size() > 0) {
//                majorLevel = "stable";
//            } else {
//                majorLevel = "safe";
//            }
//            majorGroup.setLevelType(majorLevel);
//
//            // 根据用户请求的等级类型设置学校详情，只返回用户请求的等级的学校
//            majorGroup.setRushSchools(requestedLevels.contains("rush") ?
//                convertToDirectParamsMajorAdmissionInfo(rushSchools) : null);
//            majorGroup.setStableSchools(requestedLevels.contains("stable") ?
//                convertToDirectParamsMajorAdmissionInfo(stableSchools) : null);
//            majorGroup.setSafeSchools(requestedLevels.contains("safe") ?
//                convertToDirectParamsMajorAdmissionInfo(safeSchools) : null);
//
//            log.debug("专业 {} 符合请求等级 {}，返回数据", majorName, requestedLevels);
//            return majorGroup;
//
//        } catch (Exception e) {
//            log.error("获取专业分组数据失败，专业：{}", majorName, e);
//            return null;
//        }
//    }

    /**
     * 按冲稳保等级分类学校
     */
    private DirectParamsGroupRespVO.SchoolClassificationData classifySchoolsByLevel(
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> allMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajors,
            Integer pageNo,
            Integer pageSize,
            UserProfileInfo profile,
            List<String> levelTypes) {

        log.info("开始按冲稳保等级分类学校，总专业数：{}", allMajors.size());

        // 按学校分组
        Map<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> schoolMajorsMap = allMajors.stream()
                .collect(Collectors.groupingBy(DirectParamsGroupRespVO.MajorAdmissionInfo::getSchoolName));

        // 使用 Set 来提高查找效率
        Set<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajorsSet = new HashSet<>(rushMajors);
        Set<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajorsSet = new HashSet<>(stableMajors);
        Set<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajorsSet = new HashSet<>(safeMajors);

        List<DirectParamsGroupRespVO.SchoolGroupData> rushSchools = new ArrayList<>();
        List<DirectParamsGroupRespVO.SchoolGroupData> stableSchools = new ArrayList<>();
        List<DirectParamsGroupRespVO.SchoolGroupData> safeSchools = new ArrayList<>();

        // 为每个学校确定等级
        for (Map.Entry<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> entry : schoolMajorsMap.entrySet()) {
            String schoolName = entry.getKey();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolMajors = entry.getValue();

            // 统计该学校在各等级的专业数量
            int rushCount = 0, stableCount = 0, safeCount = 0;
            for (DirectParamsGroupRespVO.MajorAdmissionInfo major : schoolMajors) {
                if (rushMajorsSet.contains(major)) {
                    rushCount++;
                } else if (stableMajorsSet.contains(major)) {
                    stableCount++;
                } else if (safeMajorsSet.contains(major)) {
                    safeCount++;
                }
            }

            // 根据专业分布确定学校等级（优先级：冲刺 > 稳妥 > 保底）
            String schoolLevel;
            if (rushCount > 0) {
                schoolLevel = "rush";
            } else if (stableCount > 0) {
                schoolLevel = "stable";
            } else {
                schoolLevel = "safe";
            }

            // 构建学校分组数据
            DirectParamsGroupRespVO.SchoolGroupData schoolGroup = createSchoolGroupData(
                    schoolName, schoolMajors, rushCount, stableCount, safeCount, schoolLevel, profile);

            // 根据等级添加到对应列表
            switch (schoolLevel) {
                case "rush":
                    rushSchools.add(schoolGroup);
                    break;
                case "stable":
                    stableSchools.add(schoolGroup);
                    break;
                case "safe":
                    safeSchools.add(schoolGroup);
                    break;
            }
        }

        // 按专业总数排序
        rushSchools.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));
        stableSchools.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));
        safeSchools.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));

        // 根据请求的等级过滤结果
        Set<String> requestedLevels = new HashSet<>();
        if (levelTypes == null || levelTypes.isEmpty()) {
            requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
        } else {
            requestedLevels.addAll(levelTypes);
        }

        // 构建分类结果
        DirectParamsGroupRespVO.SchoolClassificationData result = new DirectParamsGroupRespVO.SchoolClassificationData();
        result.setRushSchools(requestedLevels.contains("rush") ? rushSchools : new ArrayList<>());
        result.setStableSchools(requestedLevels.contains("stable") ? stableSchools : new ArrayList<>());
        result.setSafeSchools(requestedLevels.contains("safe") ? safeSchools : new ArrayList<>());
        result.setRushCount(requestedLevels.contains("rush") ? rushSchools.size() : 0);
        result.setStableCount(requestedLevels.contains("stable") ? stableSchools.size() : 0);
        result.setSafeCount(requestedLevels.contains("safe") ? safeSchools.size() : 0);

        int totalCount = 0;
        if (requestedLevels.contains("rush")) {
            totalCount += rushSchools.size();
        }
        if (requestedLevels.contains("stable")) {
            totalCount += stableSchools.size();
        }
        if (requestedLevels.contains("safe")) {
            totalCount += safeSchools.size();
        }
        result.setTotalCount(totalCount);

        log.info("学校冲稳保分类完成 - 请求等级：{}，冲刺：{}个，稳妥：{}个，保底：{}个",
                requestedLevels, rushSchools.size(), stableSchools.size(), safeSchools.size());

        return result;
    }

    /**
     * 按学校分组专业数据
     */
    private PageResult<DirectParamsGroupRespVO.SchoolGroupData> groupMajorsBySchool(
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> allMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajors,
            Integer pageNo,
            Integer pageSize,
            UserProfileInfo profile,
            Boolean includeMajorDetails,
            String targetSchoolUuid) {

        // 处理参数默认值
        if (includeMajorDetails == null) {
            includeMajorDetails = false; // 默认不返回专业详情
        }

        log.info("开始按学校分组，总专业数：{}，是否包含专业详情：{}，目标学校：{}",
                allMajors.size(), includeMajorDetails, targetSchoolUuid);

        // 优化：使用字符串键替代对象比较，避免 StackOverflowError
        Set<String> rushMajorKeys = rushMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());
        Set<String> stableMajorKeys = stableMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());
        Set<String> safeMajorKeys = safeMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());

        log.debug("构建分类键集合 - 冲刺：{}个，稳妥：{}个，保底：{}个",
                rushMajorKeys.size(), stableMajorKeys.size(), safeMajorKeys.size());

        // 按学校分组
        Map<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> schoolMajorsMap = allMajors.stream()
                .collect(Collectors.groupingBy(DirectParamsGroupRespVO.MajorAdmissionInfo::getSchoolName));

        // 如果指定了目标学校，只处理该学校的数据
        if (targetSchoolUuid != null && !targetSchoolUuid.trim().isEmpty()) {
            schoolMajorsMap = schoolMajorsMap.entrySet().stream()
                    .filter(entry -> entry.getValue().stream()
                            .anyMatch(major -> targetSchoolUuid.equals(major.getSchoolUUID())))
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            log.info("指定目标学校UUID：{}，过滤后学校数量：{}", targetSchoolUuid, schoolMajorsMap.size());
        }

        log.info("分组后学校数量：{}", schoolMajorsMap.size());

        // 构建学校分组数据
        List<DirectParamsGroupRespVO.SchoolGroupData> schoolGroupList = new ArrayList<>();

        for (Map.Entry<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> entry : schoolMajorsMap.entrySet()) {
            String schoolName = entry.getKey();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolMajors = entry.getValue();

            DirectParamsGroupRespVO.SchoolGroupData schoolGroup = new DirectParamsGroupRespVO.SchoolGroupData();
            schoolGroup.setSchoolName(schoolName);

            // 获取学校UUID（从第一个专业中获取）
            if (!schoolMajors.isEmpty()) {
                schoolGroup.setSchoolUuid(schoolMajors.get(0).getSchoolUUID());
            }

            // 分类该学校的专业（使用 Set 提高查找效率）
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolRushMajors = new ArrayList<>();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolStableMajors = new ArrayList<>();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolSafeMajors = new ArrayList<>();

            for (DirectParamsGroupRespVO.MajorAdmissionInfo major : schoolMajors) {
                String majorKey = major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear();
                if (rushMajorKeys.contains(majorKey)) {
                    schoolRushMajors.add(major);
                } else if (stableMajorKeys.contains(majorKey)) {
                    schoolStableMajors.add(major);
                } else if (safeMajorKeys.contains(majorKey)) {
                    schoolSafeMajors.add(major);
                }
            }

            // 根据专业分布确定学校等级（优先级：冲刺 > 稳妥 > 保底）
            String schoolLevel;
            if (schoolRushMajors.size() > 0) {
                schoolLevel = "rush";
            } else if (schoolStableMajors.size() > 0) {
                schoolLevel = "stable";
            } else {
                schoolLevel = "safe";
            }

            schoolGroup.setLevelType(schoolLevel);
            schoolGroup.setRushCount(schoolRushMajors.size());
            schoolGroup.setStableCount(schoolStableMajors.size());
            schoolGroup.setSafeCount(schoolSafeMajors.size());
            schoolGroup.setTotalCount(schoolMajors.size());
            schoolGroup.setHasMajorDetails(includeMajorDetails);

            // 根据参数决定是否返回专业详情数据
            if (includeMajorDetails) {
                schoolGroup.setRushMajors(schoolRushMajors);
                schoolGroup.setStableMajors(schoolStableMajors);
                schoolGroup.setSafeMajors(schoolSafeMajors);
                log.debug("学校 {} 返回专业详情，冲刺：{}个，稳妥：{}个，保底：{}个",
                        schoolName, schoolRushMajors.size(), schoolStableMajors.size(), schoolSafeMajors.size());
            } else {
                // 不返回专业详情，设置为null以减少数据传输
                schoolGroup.setRushMajors(null);
                schoolGroup.setStableMajors(null);
                schoolGroup.setSafeMajors(null);
                log.debug("学校 {} 不返回专业详情，仅返回统计信息", schoolName);
            }

            // 获取学校基础信息
            try {
                DirectParamsGroupRespVO.SchoolBasicInfo schoolInfo = getSchoolBasicInfo(schoolGroup.getSchoolUuid());
                schoolGroup.setSchoolInfo(schoolInfo);
            } catch (Exception e) {
                log.warn("获取学校基础信息失败，学校：{}，错误：{}", schoolName, e.getMessage());
            }

            schoolGroupList.add(schoolGroup);
        }

        // 按总专业数量排序（降序）
        schoolGroupList.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));

        // 分页处理
        int total = schoolGroupList.size();
        int start = (pageNo - 1) * pageSize;
        int end = Math.min(start + pageSize, total);

        List<DirectParamsGroupRespVO.SchoolGroupData> pagedList;
        if (start >= total) {
            pagedList = new ArrayList<>();
        } else {
            pagedList = schoolGroupList.subList(start, end);
        }

        log.info("按学校分组完成，总学校数：{}，当前页：{}，每页：{}，返回：{}个学校",
                total, pageNo, pageSize, pagedList.size());

        return new PageResult<>(pagedList, (long) total);
    }

    /**
     * 创建学校分组数据的辅助方法
     */
    private DirectParamsGroupRespVO.SchoolGroupData createSchoolGroupData(
            String schoolName,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolMajors,
            int rushCount,
            int stableCount,
            int safeCount,
            String levelType,
            UserProfileInfo profile) {

        DirectParamsGroupRespVO.SchoolGroupData schoolGroup = new DirectParamsGroupRespVO.SchoolGroupData();
        schoolGroup.setSchoolName(schoolName);
        schoolGroup.setLevelType(levelType);

        // 获取学校UUID（从第一个专业中获取）
        if (!schoolMajors.isEmpty()) {
            schoolGroup.setSchoolUuid(schoolMajors.get(0).getSchoolUUID());
        }

        // 分类该学校的专业
        List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolRushMajors = new ArrayList<>();
        List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolStableMajors = new ArrayList<>();
        List<DirectParamsGroupRespVO.MajorAdmissionInfo> schoolSafeMajors = new ArrayList<>();

        // 这里需要重新分类，因为传入的 rushCount 等只是统计数字
        Set<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajorsSet = new HashSet<>();
        Set<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajorsSet = new HashSet<>();
        Set<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajorsSet = new HashSet<>();

        // 重新获取分类数据（这里可以优化，但为了代码清晰暂时这样处理）
        for (DirectParamsGroupRespVO.MajorAdmissionInfo major : schoolMajors) {
            // 根据分数判断等级
            try {
                int majorScore = Integer.parseInt(major.getLowestScore());
                int userScore = profile.getTotalScore();
                int scoreDiff = majorScore - userScore;

                if (scoreDiff > 5) {
                    schoolRushMajors.add(major);
                } else if (scoreDiff >= -5 && scoreDiff <= 5) {
                    schoolStableMajors.add(major);
                } else if (scoreDiff < -5) {
                    schoolSafeMajors.add(major);
                }
            } catch (NumberFormatException e) {
                schoolStableMajors.add(major);
            }
        }

        schoolGroup.setRushMajors(schoolRushMajors);
        schoolGroup.setStableMajors(schoolStableMajors);
        schoolGroup.setSafeMajors(schoolSafeMajors);
        schoolGroup.setRushCount(schoolRushMajors.size());
        schoolGroup.setStableCount(schoolStableMajors.size());
        schoolGroup.setSafeCount(schoolSafeMajors.size());
        schoolGroup.setTotalCount(schoolMajors.size());

        // 获取学校基础信息
        try {
            DirectParamsGroupRespVO.SchoolBasicInfo schoolInfo = getSchoolBasicInfo(schoolGroup.getSchoolUuid());
            schoolGroup.setSchoolInfo(schoolInfo);
        } catch (Exception e) {
            log.warn("获取学校基础信息失败，学校：{}，错误：{}", schoolName, e.getMessage());
        }

        return schoolGroup;
    }

    /**
     * 按冲稳保等级分类专业
     */
    private DirectParamsGroupRespVO.MajorClassificationData classifyMajorsByLevel(
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> allMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajors,
            Integer pageNo,
            Integer pageSize,
            List<String> levelTypes) {

        log.info("开始按冲稳保等级分类专业，总专业数：{}", allMajors.size());

        // 按专业名称分组（去除括号内容）
        Map<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> majorSchoolsMap = allMajors.stream()
                .collect(Collectors.groupingBy(major -> removeBrackets(major.getMajorName())));

        // 使用字符串键替代对象比较，避免 StackOverflowError
        Set<String> rushMajorKeys = rushMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());
        Set<String> stableMajorKeys = stableMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());
        Set<String> safeMajorKeys = safeMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());

        List<DirectParamsGroupRespVO.MajorGroupData> rushMajorGroups = new ArrayList<>();
        List<DirectParamsGroupRespVO.MajorGroupData> stableMajorGroups = new ArrayList<>();
        List<DirectParamsGroupRespVO.MajorGroupData> safeMajorGroups = new ArrayList<>();

        // 为每个专业确定等级
        for (Map.Entry<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> entry : majorSchoolsMap.entrySet()) {
            String majorName = entry.getKey();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorSchools = entry.getValue();

            // 统计该专业在各等级的学校数量
            int rushCount = 0, stableCount = 0, safeCount = 0;
            for (DirectParamsGroupRespVO.MajorAdmissionInfo major : majorSchools) {
                String majorKey = major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear();
                if (rushMajorKeys.contains(majorKey)) {
                    rushCount++;
                } else if (stableMajorKeys.contains(majorKey)) {
                    stableCount++;
                } else if (safeMajorKeys.contains(majorKey)) {
                    safeCount++;
                }
            }

            // 根据学校分布确定专业等级（优先级：冲刺 > 稳妥 > 保底）
            String majorLevel;
            if (rushCount > 0) {
                majorLevel = "rush";
            } else if (stableCount > 0) {
                majorLevel = "stable";
            } else {
                majorLevel = "safe";
            }

            // 构建专业分组数据
            DirectParamsGroupRespVO.MajorGroupData majorGroup = createMajorGroupData(
                    majorName, majorSchools, rushCount, stableCount, safeCount, majorLevel);

            // 根据等级添加到对应列表
            switch (majorLevel) {
                case "rush":
                    rushMajorGroups.add(majorGroup);
                    break;
                case "stable":
                    stableMajorGroups.add(majorGroup);
                    break;
                case "safe":
                    safeMajorGroups.add(majorGroup);
                    break;
            }
        }

        // 按学校总数排序
        rushMajorGroups.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));
        stableMajorGroups.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));
        safeMajorGroups.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));

        // 根据请求的等级过滤结果
        Set<String> requestedLevels = new HashSet<>();
        if (levelTypes == null || levelTypes.isEmpty()) {
            requestedLevels.addAll(Arrays.asList("rush", "stable", "safe")); // 默认返回所有等级
        } else {
            requestedLevels.addAll(levelTypes);
        }

        // 构建分类结果
        DirectParamsGroupRespVO.MajorClassificationData result = new DirectParamsGroupRespVO.MajorClassificationData();
        result.setRushMajors(requestedLevels.contains("rush") ? rushMajorGroups : new ArrayList<>());
        result.setStableMajors(requestedLevels.contains("stable") ? stableMajorGroups : new ArrayList<>());
        result.setSafeMajors(requestedLevels.contains("safe") ? safeMajorGroups : new ArrayList<>());
        result.setRushCount(requestedLevels.contains("rush") ? rushMajorGroups.size() : 0);
        result.setStableCount(requestedLevels.contains("stable") ? stableMajorGroups.size() : 0);
        result.setSafeCount(requestedLevels.contains("safe") ? safeMajorGroups.size() : 0);

        int totalCount = 0;
        if (requestedLevels.contains("rush")) {
            totalCount += rushMajorGroups.size();
        }
        if (requestedLevels.contains("stable")) {
            totalCount += stableMajorGroups.size();
        }
        if (requestedLevels.contains("safe")) {
            totalCount += safeMajorGroups.size();
        }
        result.setTotalCount(totalCount);

        log.info("专业冲稳保分类完成 - 请求等级：{}，冲刺：{}个，稳妥：{}个，保底：{}个",
                requestedLevels, rushMajorGroups.size(), stableMajorGroups.size(), safeMajorGroups.size());

        return result;
    }

    /**
     * 按专业分组学校数据
     */
    private PageResult<DirectParamsGroupRespVO.MajorGroupData> groupMajorsByMajor(
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> allMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> rushMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> stableMajors,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> safeMajors,
            Integer pageNo,
            Integer pageSize) {

        log.info("开始按专业分组，总专业数：{}", allMajors.size());

        // 优化：使用字符串键替代对象比较，避免 StackOverflowError
        Set<String> rushMajorKeys = rushMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());
        Set<String> stableMajorKeys = stableMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());
        Set<String> safeMajorKeys = safeMajors.stream()
                .map(major -> major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear())
                .collect(Collectors.toSet());

        // 按专业名称分组（去除括号内容）
        Map<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> majorSchoolsMap = allMajors.stream()
                .collect(Collectors.groupingBy(major -> removeBrackets(major.getMajorName())));

        log.info("分组后专业数量：{}", majorSchoolsMap.size());

        // 构建专业分组数据
        List<DirectParamsGroupRespVO.MajorGroupData> majorGroupList = new ArrayList<>();

        for (Map.Entry<String, List<DirectParamsGroupRespVO.MajorAdmissionInfo>> entry : majorSchoolsMap.entrySet()) {
            String majorName = entry.getKey();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorSchools = entry.getValue();

            DirectParamsGroupRespVO.MajorGroupData majorGroup = new DirectParamsGroupRespVO.MajorGroupData();
            majorGroup.setMajorName(majorName);

            // 获取专业类别信息（从第一个专业中获取）
            if (!majorSchools.isEmpty()) {
                // 这里可以根据需要从专业信息中获取类别，暂时设置为空
                majorGroup.setClassOne(""); // 可以从专业数据中获取
                majorGroup.setClassTwo(""); // 可以从专业数据中获取
            }

            // 分类该专业的学校（使用 Set 提高查找效率）
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorRushSchools = new ArrayList<>();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorStableSchools = new ArrayList<>();
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorSafeSchools = new ArrayList<>();

            for (DirectParamsGroupRespVO.MajorAdmissionInfo major : majorSchools) {
                String majorKey = major.getSchoolUUID() + ":" + major.getMajorName() + ":" + major.getYear();
                if (rushMajorKeys.contains(majorKey)) {
                    majorRushSchools.add(major);
                } else if (stableMajorKeys.contains(majorKey)) {
                    majorStableSchools.add(major);
                } else if (safeMajorKeys.contains(majorKey)) {
                    majorSafeSchools.add(major);
                }
            }

            // 根据学校分布确定专业等级（优先级：冲刺 > 稳妥 > 保底）
            String majorLevel;
            if (majorRushSchools.size() > 0) {
                majorLevel = "rush";
            } else if (majorStableSchools.size() > 0) {
                majorLevel = "stable";
            } else {
                majorLevel = "safe";
            }

            majorGroup.setLevelType(majorLevel);
            majorGroup.setRushSchools(majorRushSchools);
            majorGroup.setStableSchools(majorStableSchools);
            majorGroup.setSafeSchools(majorSafeSchools);
            majorGroup.setRushCount(majorRushSchools.size());
            majorGroup.setStableCount(majorStableSchools.size());
            majorGroup.setSafeCount(majorSafeSchools.size());
            majorGroup.setTotalCount(majorSchools.size());

            majorGroupList.add(majorGroup);
        }

        // 按总学校数量排序（降序）
        majorGroupList.sort((a, b) -> Integer.compare(b.getTotalCount(), a.getTotalCount()));

        // 分页处理
        int total = majorGroupList.size();
        int start = (pageNo - 1) * pageSize;
        int end = Math.min(start + pageSize, total);

        List<DirectParamsGroupRespVO.MajorGroupData> pagedList;
        if (start >= total) {
            pagedList = new ArrayList<>();
        } else {
            pagedList = majorGroupList.subList(start, end);
        }

        log.info("按专业分组完成，总专业数：{}，当前页：{}，每页：{}，返回：{}个专业",
                total, pageNo, pageSize, pagedList.size());

        return new PageResult<>(pagedList, (long) total);
    }

    /**
     * 创建专业分组数据的辅助方法
     */
    private DirectParamsGroupRespVO.MajorGroupData createMajorGroupData(
            String majorName,
            List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorSchools,
            int rushCount,
            int stableCount,
            int safeCount,
            String levelType) {

        DirectParamsGroupRespVO.MajorGroupData majorGroup = new DirectParamsGroupRespVO.MajorGroupData();
        majorGroup.setMajorName(majorName);
        majorGroup.setLevelType(levelType);

        // 获取专业类别信息（从第一个专业中获取）
        if (!majorSchools.isEmpty()) {
            // 这里可以根据需要从专业数据中获取类别，暂时设置为空
            majorGroup.setClassOne(""); // 可以从专业数据中获取
            majorGroup.setClassTwo(""); // 可以从专业数据中获取
        }

        // 分类该专业的学校
        List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorRushSchools = new ArrayList<>();
        List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorStableSchools = new ArrayList<>();
        List<DirectParamsGroupRespVO.MajorAdmissionInfo> majorSafeSchools = new ArrayList<>();

        // 重新分类学校（根据分数）
        for (DirectParamsGroupRespVO.MajorAdmissionInfo major : majorSchools) {
            try {
                int majorScore = Integer.parseInt(major.getLowestScore());
                // 这里需要用户分数，但方法参数中没有，暂时使用固定值或从其他地方获取
                // 为了简化，这里直接按分数范围分类
                if (majorScore >= 600) {
                    majorRushSchools.add(major);
                } else if (majorScore >= 500) {
                    majorStableSchools.add(major);
                } else {
                    majorSafeSchools.add(major);
                }
            } catch (NumberFormatException e) {
                majorStableSchools.add(major);
            }
        }

        majorGroup.setRushSchools(majorRushSchools);
        majorGroup.setStableSchools(majorStableSchools);
        majorGroup.setSafeSchools(majorSafeSchools);
        majorGroup.setRushCount(majorRushSchools.size());
        majorGroup.setStableCount(majorStableSchools.size());
        majorGroup.setSafeCount(majorSafeSchools.size());
        majorGroup.setTotalCount(majorSchools.size());

        return majorGroup;
    }

    /**
     * 获取学校基础信息
     */
    private DirectParamsGroupRespVO.SchoolBasicInfo getSchoolBasicInfo(String schoolUuid) {
        if (schoolUuid == null || schoolUuid.trim().isEmpty()) {
            return null;
        }

        try {
            // 查询学校基础信息
            CollegeDO collegeDO = collegeMapper.selectOne(new LambdaQueryWrapperX<CollegeDO>()
                    .eq(CollegeDO::getSchoolUuid, schoolUuid));

            if (collegeDO == null) {
                log.warn("未找到学校基础信息，schoolUuid: {}", schoolUuid);
                return null;
            }

            DirectParamsGroupRespVO.SchoolBasicInfo schoolInfo = new DirectParamsGroupRespVO.SchoolBasicInfo();
            schoolInfo.setSchoolUuid(collegeDO.getSchoolUuid());
            schoolInfo.setCollegeName(collegeDO.getCollegeName());
            schoolInfo.setProvince(collegeDO.getProvince());
            schoolInfo.setCity(collegeDO.getCity());
            schoolInfo.setCollegeType(collegeDO.getCollegeType());
            schoolInfo.setIs985(collegeDO.getIs985());
            schoolInfo.setIs211(collegeDO.getIs211());
            schoolInfo.setIsDualClass(collegeDO.getIsDualClass());
            schoolInfo.setCoverImage(collegeDO.getCoverImage());

            return schoolInfo;

        } catch (Exception e) {
            log.error("获取学校基础信息时发生错误，schoolUuid: {}", schoolUuid, e);
            return null;
        }
    }

    /**
     * 转换单个MajorAdmissionInfo对象为DirectParamsGroupRespVO.MajorAdmissionInfo类型
     */
    private DirectParamsGroupRespVO.MajorAdmissionInfo convertToDirectParamsMajorAdmissionInfo(MajorAdmissionInfo source) {
        if (source == null) {
            return null;
        }

        DirectParamsGroupRespVO.MajorAdmissionInfo target = new DirectParamsGroupRespVO.MajorAdmissionInfo();

        // 复制基本字段
        target.setProvinceName(source.getProvinceName());
        target.setSchoolUUID(source.getSchoolUUID());
        target.setSchoolName(source.getSchoolName());
        target.setMajorName(source.getMajorName());
        target.setMajorCode(source.getMajorCode() != null ? source.getMajorCode().toString() : null);
        target.setYear(source.getYear());
        target.setHighScore(source.getHighScore());
        target.setAverageScore(source.getAverageScore());
        target.setLowestScore(source.getLowestScore());
        target.setLowestSection(source.getLowestSection());
        target.setBatchName(source.getBatchName());
        target.setTypeName(source.getTypeName());
        target.setProScore(source.getProScore());
        target.setSubjectSelection(source.getSubjectSelection());
        target.setMajorStandardCode(source.getMajorStandardCode());

        // 复制历史数据字段
        if (source.getHistoricalData() != null && !source.getHistoricalData().isEmpty()) {
            List<DirectParamsGroupRespVO.HistoricalYearData> historicalDataList = new ArrayList<>();
            for (MajorAdmissionInfo.HistoricalYearData sourceHistorical : source.getHistoricalData()) {
                DirectParamsGroupRespVO.HistoricalYearData targetHistorical = new DirectParamsGroupRespVO.HistoricalYearData();
                targetHistorical.setYear(sourceHistorical.getYear());
                targetHistorical.setHighScore(sourceHistorical.getHighScore());
                targetHistorical.setAverageScore(sourceHistorical.getAverageScore());
                targetHistorical.setLowestScore(sourceHistorical.getLowestScore());
                targetHistorical.setLowestSection(sourceHistorical.getLowestSection());
                historicalDataList.add(targetHistorical);
            }
            target.setHistoricalData(historicalDataList);
        }
        target.setHistoricalDataLoading(source.getHistoricalDataLoading());

        // 复制招生计划数据字段
        if (source.getEnrollmentPlanData() != null && !source.getEnrollmentPlanData().isEmpty()) {
            List<DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo> enrollmentPlanList = new ArrayList<>();
            for (CollegeEnrollmentPlanInfo sourceEnrollment : source.getEnrollmentPlanData()) {
                DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo targetEnrollment = new DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo();
                targetEnrollment.setYear(sourceEnrollment.getYear());
                targetEnrollment.setEnrollmentPlan(sourceEnrollment.getEnrollmentNumbers()); // 使用正确的字段名
                targetEnrollment.setTuition(""); // CollegeEnrollmentPlanInfo 没有学费字段，设置为空
                targetEnrollment.setCourseSelectionRequirements(sourceEnrollment.getCourseSelectionRequirements());
                targetEnrollment.setMajorRemarks(""); // CollegeEnrollmentPlanInfo 没有专业备注字段，设置为空

                // 专业组相关字段
                targetEnrollment.setSpecialGroup(sourceEnrollment.getSpecialGroup());
                targetEnrollment.setSpecialCode(sourceEnrollment.getSpecialCode());
                targetEnrollment.setSpecialGroupName(sourceEnrollment.getSpecialGroupName());

                // 其他详细字段
                targetEnrollment.setInSchoolYears(sourceEnrollment.getInSchoolYears());
                targetEnrollment.setClassOne(sourceEnrollment.getClassOne());
                targetEnrollment.setClassTwo(sourceEnrollment.getClassTwo());
                targetEnrollment.setBatchName(sourceEnrollment.getBatchName());
                targetEnrollment.setType(sourceEnrollment.getType());
                targetEnrollment.setSchoolName(sourceEnrollment.getSchoolName());
                targetEnrollment.setSchoolUuid(sourceEnrollment.getSchoolUuid());
                targetEnrollment.setCollegeMajorName(sourceEnrollment.getCollegeMajorName());
                targetEnrollment.setCollegeMajorCode(sourceEnrollment.getCollegeMajorCode());
                targetEnrollment.setProvinceName(sourceEnrollment.getProvinceName());

                enrollmentPlanList.add(targetEnrollment);
            }
            target.setEnrollmentPlanData(enrollmentPlanList);
        }
        target.setEnrollmentPlanDataLoading(source.getEnrollmentPlanDataLoading());

        return target;
    }

    /**
     * 转换MajorAdmissionInfo类型为DirectParamsGroupRespVO.MajorAdmissionInfo类型
     */
    private List<DirectParamsGroupRespVO.MajorAdmissionInfo> convertToDirectParamsMajorAdmissionInfo(
            List<MajorAdmissionInfo> sourceList) {
        if (sourceList == null || sourceList.isEmpty()) {
            return new ArrayList<>();
        }

        List<DirectParamsGroupRespVO.MajorAdmissionInfo> resultList = new ArrayList<>();
        for (MajorAdmissionInfo source : sourceList) {
            DirectParamsGroupRespVO.MajorAdmissionInfo target = new DirectParamsGroupRespVO.MajorAdmissionInfo();

            // 复制基本字段
            target.setProvinceName(source.getProvinceName());
            target.setSchoolUUID(source.getSchoolUUID());
            target.setSchoolName(source.getSchoolName());
            target.setMajorName(source.getMajorName());
            target.setMajorCode(source.getMajorCode() != null ? source.getMajorCode().toString() : null);
            target.setYear(source.getYear());
            target.setHighScore(source.getHighScore());
            target.setAverageScore(source.getAverageScore());
            target.setLowestScore(source.getLowestScore());
            target.setLowestSection(source.getLowestSection());
            target.setBatchName(source.getBatchName());
            target.setTypeName(source.getTypeName());
            target.setProScore(source.getProScore());
            target.setSubjectSelection(source.getSubjectSelection());
            target.setMajorStandardCode(source.getMajorStandardCode());

            // 复制历史数据字段
            if (source.getHistoricalData() != null && !source.getHistoricalData().isEmpty()) {
                List<DirectParamsGroupRespVO.HistoricalYearData> historicalDataList = new ArrayList<>();
                for (MajorAdmissionInfo.HistoricalYearData sourceHistorical : source.getHistoricalData()) {
                    DirectParamsGroupRespVO.HistoricalYearData targetHistorical = new DirectParamsGroupRespVO.HistoricalYearData();
                    targetHistorical.setYear(sourceHistorical.getYear());
                    targetHistorical.setHighScore(sourceHistorical.getHighScore());
                    targetHistorical.setAverageScore(sourceHistorical.getAverageScore());
                    targetHistorical.setLowestScore(sourceHistorical.getLowestScore());
                    targetHistorical.setLowestSection(sourceHistorical.getLowestSection());
                    historicalDataList.add(targetHistorical);
                }
                target.setHistoricalData(historicalDataList);
            }
            target.setHistoricalDataLoading(source.getHistoricalDataLoading());

            // 复制招生计划数据字段
            if (source.getEnrollmentPlanData() != null && !source.getEnrollmentPlanData().isEmpty()) {
                List<DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo> enrollmentPlanList = new ArrayList<>();
                for (CollegeEnrollmentPlanInfo sourceEnrollment : source.getEnrollmentPlanData()) {
                    DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo targetEnrollment = new DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo();
                    targetEnrollment.setYear(sourceEnrollment.getYear());
                    targetEnrollment.setEnrollmentPlan(sourceEnrollment.getEnrollmentNumbers()); // 使用正确的字段名
                    targetEnrollment.setTuition(""); // CollegeEnrollmentPlanInfo 没有学费字段，设置为空
                    targetEnrollment.setCourseSelectionRequirements(sourceEnrollment.getCourseSelectionRequirements());
                    targetEnrollment.setMajorRemarks(""); // CollegeEnrollmentPlanInfo 没有专业备注字段，设置为空

                    // 专业组相关字段
                    targetEnrollment.setSpecialGroup(sourceEnrollment.getSpecialGroup());
                    targetEnrollment.setSpecialCode(sourceEnrollment.getSpecialCode());
                    targetEnrollment.setSpecialGroupName(sourceEnrollment.getSpecialGroupName());

                    // 其他详细字段
                    targetEnrollment.setInSchoolYears(sourceEnrollment.getInSchoolYears());
                    targetEnrollment.setClassOne(sourceEnrollment.getClassOne());
                    targetEnrollment.setClassTwo(sourceEnrollment.getClassTwo());
                    targetEnrollment.setBatchName(sourceEnrollment.getBatchName());
                    targetEnrollment.setType(sourceEnrollment.getType());
                    targetEnrollment.setSchoolName(sourceEnrollment.getSchoolName());
                    targetEnrollment.setSchoolUuid(sourceEnrollment.getSchoolUuid());
                    targetEnrollment.setCollegeMajorName(sourceEnrollment.getCollegeMajorName());
                    targetEnrollment.setCollegeMajorCode(sourceEnrollment.getCollegeMajorCode());
                    targetEnrollment.setProvinceName(sourceEnrollment.getProvinceName());

                    enrollmentPlanList.add(targetEnrollment);
                }
                target.setEnrollmentPlanData(enrollmentPlanList);
            }
            target.setEnrollmentPlanDataLoading(source.getEnrollmentPlanDataLoading());

            resultList.add(target);
        }

        return resultList;
    }

    /**
     * 批量查询最新一年专业录取分数数据（性能优化版本V2）
     * 优化：只查询2024年数据，不再查询近三年数据
     * @param majors 专业列表
     * @param profile 用户信息
     */
    private void batchQueryLatestYearAdmissionScoresV2(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return;
        }

        long startTime = System.currentTimeMillis();
        log.info("开始为 {} 个专业批量查询最新一年录取分数数据（V2优化版本）", majors.size());

        try {
            // 收集学校UUID和专业名称
            Set<String> schoolUUIDs = majors.stream()
                    .map(MajorAdmissionInfo::getSchoolUUID)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());

            Set<String> majorNames = majors.stream()
                    .map(MajorAdmissionInfo::getMajorName)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());

            log.info("收集到 {} 个学校UUID，{} 个专业名称", schoolUUIDs.size(), majorNames.size());

            // 只查询2024年的数据
            Integer year = 2024;
            List<MajorAdmissionDO> yearData = majorAdmissionService.batchQueryAdmissionScores(
                    new ArrayList<>(schoolUUIDs),
                    new ArrayList<>(majorNames),
                    year,
                    profile.getTypeName(),
                    profile.getProvince()
            );

            if (yearData != null && !yearData.isEmpty()) {
                log.info("查询到 {} 年的录取分数数据 {} 条", year, yearData.size());

                // 按学校UUID+专业名称+年份+批次+类型+选科组合分组，避免数据丢失
                Map<String, List<MajorAdmissionDO>> admissionDataMap = new HashMap<>();
                for (MajorAdmissionDO admission : yearData) {
                    String key = buildAdmissionDataKey(admission);
                    admissionDataMap.computeIfAbsent(key, k -> new ArrayList<>()).add(admission);
                }

                log.info("分组完成，共获取 {} 个学校专业组合的数据", admissionDataMap.size());

                // 为每个专业设置历史数据
                int successCount = 0;
                for (MajorAdmissionInfo major : majors) {
                    // 查找匹配的录取数据，使用增强版匹配方法避免数据丢失
                    List<MajorAdmissionDO> admissionList = findMatchingAdmissionDataEnhanced(admissionDataMap, major, profile);

                    // 如果增强版方法仍然没有找到数据，使用原始方法作为备用
                    if (admissionList.isEmpty()) {
                        admissionList = findMatchingAdmissionData(admissionDataMap, major, profile);
                        if (!admissionList.isEmpty()) {
                            log.info("备用方法找到数据 - 学校: {}, 专业: {}, 数据条数: {}",
                                    major.getSchoolName(), major.getMajorName(), admissionList.size());
                        }
                    }

                    if (admissionList != null && !admissionList.isEmpty()) {
                        // 转换为历史数据对象并去重
                        Set<MajorAdmissionInfo.HistoricalYearData> uniqueDataSet = new HashSet<>();
                        List<MajorAdmissionInfo.HistoricalYearData> deduplicatedData = new ArrayList<>();

                        for (MajorAdmissionDO admission : admissionList) {
                            MajorAdmissionInfo.HistoricalYearData historicalData = convertToHistoricalYearData(admission);
                            if (historicalData != null && uniqueDataSet.add(historicalData)) {
                                deduplicatedData.add(historicalData);
                            }
                        }

                        if (!deduplicatedData.isEmpty()) {
                            major.setHistoricalData(deduplicatedData);
                            successCount++;
                            log.debug("专业 {} - {} 设置了 {} 条最新一年录取分数数据",
                                    major.getSchoolName(), major.getMajorName(), deduplicatedData.size());
                        }
                    }
                }

                long endTime = System.currentTimeMillis();
                log.info("批量查询最新一年录取分数数据完成（V2优化版本），耗时: {}ms，成功设置数据的专业数量: {}/{}",
                        endTime - startTime, successCount, majors.size());
            } else {
                log.info("未查询到 {} 年的录取分数数据", year);
            }

        } catch (Exception e) {
            log.error("批量查询最新一年录取分数数据失败（V2优化版本）", e);
        }
    }

    /**
     * 批量查询三年招生计划数据（性能优化版本V2）
     * 修复：改为逐个查询每个专业的招生计划数据，确保100%准确性
     * 新增：多线程并发查询，大幅提升查询速度
     * 新增：根据用户选科要求过滤招生计划数据
     * 新增：查询近三年（2024、2023、2022）招生计划数据
     * @param majors 专业列表
     * @param profile 用户信息
     */
    private void batchQueryLatestYearEnrollmentPlansV2(List<MajorAdmissionInfo> majors, UserProfileInfo profile) {
        if (majors == null || majors.isEmpty()) {
            return;
        }

        long startTime = System.currentTimeMillis();
        log.info("开始为 {} 个专业多线程查询近三年招生计划数据（V2优化版本）", majors.size());

        try {
            // 查询近三年的招生计划数据
            List<Integer> years = Arrays.asList(2025, 2024, 2023);

            // 获取用户选科信息
            Set<String> userSubjects = new HashSet<>();
            if (profile.getSubjects() != null && !profile.getSubjects().isEmpty()) {
                userSubjects.addAll(profile.getSubjects());
            }

            // 使用原子计数器来统计成功数量（线程安全）
            AtomicInteger successCount = new AtomicInteger(0);
            AtomicInteger processedCount = new AtomicInteger(0);
            AtomicInteger filteredCount = new AtomicInteger(0); // 统计被选科要求过滤掉的数量

            // 创建并发任务列表
            List<CompletableFuture<Void>> futures = new ArrayList<>();

            // 为每个专业创建一个异步查询任务
            for (int i = 0; i < majors.size(); i++) {
                final int index = i;
                final MajorAdmissionInfo major = majors.get(i);

                if (major.getSchoolName() == null || major.getMajorName() == null) {
                    log.debug("专业 {} 的学校名称或专业名称为空，跳过", index + 1);
                    continue;
                }

                // 创建异步任务
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    try {
                        // 查询近三年的招生计划数据
                        List<CollegeEnrollmentPlanInfo> allEnrollmentPlans = new ArrayList<>();

                        for (Integer year : years) {
                            try {
                                // 查询单个学校-专业对在指定年份的招生计划数据（支持专业组智能匹配）
                                // 从专业录取信息中获取专业组信息用于智能匹配
                                String subjectGroupForMatching = major.getSubjectGroup();
                                List<CollegeEnrollmentPlanInfo> yearEnrollmentPlanData = collegeEnrollmentPlanService
                                        .getEnrollmentPlanForMajorWithSubjectGroup(major.getSchoolName(), major.getMajorName(),
                                                profile.getProvince(), profile.getTypeName(), year, subjectGroupForMatching);
                                
                                log.debug("专业组智能匹配查询: 学校={}, 专业={}, 年份={}, 专业组={}", 
                                        major.getSchoolName(), major.getMajorName(), year, subjectGroupForMatching);

                                if (yearEnrollmentPlanData != null && !yearEnrollmentPlanData.isEmpty()) {
                                    allEnrollmentPlans.addAll(yearEnrollmentPlanData);
                                    log.debug("专业 {} - {} 在 {} 年找到 {} 条招生计划数据",
                                            major.getSchoolName(), major.getMajorName(), year, yearEnrollmentPlanData.size());
                                }
                            } catch (Exception e) {
                                log.warn("查询专业 {} - {} 在 {} 年的招生计划数据失败: {}",
                                        major.getSchoolName(), major.getMajorName(), year, e.getMessage());
                            }
                        }

                        if (!allEnrollmentPlans.isEmpty()) {
                            // 根据用户选科要求过滤招生计划数据
                            List<CollegeEnrollmentPlanInfo> filteredEnrollmentPlanData = new ArrayList<>();

                            for (CollegeEnrollmentPlanInfo planInfo : allEnrollmentPlans) {
                                String courseSelectionRequirements = planInfo.getCourseSelectionRequirements();

                                // 如果没有选科要求，则认为符合条件
                                if (courseSelectionRequirements == null || courseSelectionRequirements.trim().isEmpty()
                                        || "不限".equals(courseSelectionRequirements) || "无".equals(courseSelectionRequirements)) {
                                    filteredEnrollmentPlanData.add(planInfo);
                                    continue;
                                }

                                // 检查用户选科是否满足要求
                                if (checkSubjectRequirements(userSubjects, courseSelectionRequirements)) {
                                    filteredEnrollmentPlanData.add(planInfo);
                                } else {
                                    log.debug("专业 {} - {} 的招生计划因选科要求不符被过滤：用户选科 {} vs 要求 {}",
                                            major.getSchoolName(), major.getMajorName(), userSubjects, courseSelectionRequirements);
                                    filteredCount.incrementAndGet();
                                }
                            }

                            // 只有符合选科要求的招生计划数据才设置到专业对象中
                            if (!filteredEnrollmentPlanData.isEmpty()) {
                                // 去重处理（按年份、批次等去重）
                                List<CollegeEnrollmentPlanInfo> deduplicatedPlans = deduplicateEnrollmentPlans(filteredEnrollmentPlanData);
                                major.setEnrollmentPlanData(deduplicatedPlans);
                                successCount.incrementAndGet();
                                log.debug("专业 {}/{}: {} - {} 查询到 {} 条招生计划数据，过滤后剩余 {} 条，去重后剩余 {} 条",
                                        index + 1, majors.size(), major.getSchoolName(), major.getMajorName(),
                                        allEnrollmentPlans.size(), filteredEnrollmentPlanData.size(), deduplicatedPlans.size());
                            } else {
                                log.debug("专业 {}/{}: {} - {} 查询到 {} 条招生计划数据，但全部因选科要求不符被过滤",
                                        index + 1, majors.size(), major.getSchoolName(), major.getMajorName(),
                                        allEnrollmentPlans.size());
                            }
                        } else {
                            log.debug("专业 {}/{}: {} - {} 未找到近三年招生计划数据",
                                    index + 1, majors.size(), major.getSchoolName(), major.getMajorName());
                        }

                    } catch (Exception e) {
                        log.warn("查询专业 {} - {} 的招生计划数据失败: {}",
                                major.getSchoolName(), major.getMajorName(), e.getMessage());
                    } finally {
                        // 更新处理计数并输出进度
                        int processed = processedCount.incrementAndGet();
                        if (processed % 100 == 0) {
                            log.info("已处理 {}/{} 个专业，成功查询到数据的专业数量: {}，选科过滤数量: {}",
                                    processed, majors.size(), successCount.get(), filteredCount.get());
                        }
                    }
                }, executorService); // 使用现有的线程池

                futures.add(future);
            }

            // 等待所有任务完成，设置超时时间
            try {
                CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
                allFutures.get(5, TimeUnit.MINUTES); // 设置5分钟超时

                log.info("所有招生计划查询任务完成");
            } catch (TimeoutException e) {
                log.warn("招生计划查询任务超时，已完成的任务将保留结果");
                // 取消未完成的任务
                futures.forEach(future -> future.cancel(true));
            }

            long endTime = System.currentTimeMillis();
            log.info("多线程查询近三年招生计划数据完成（V2优化版本），耗时: {}ms，成功设置数据的专业数量: {}/{}，选科过滤数量: {}",
                    endTime - startTime, successCount.get(), majors.size(), filteredCount.get());

            // 为成功查询到招生计划数据的专业查询近三年录取分数线数据
            List<MajorAdmissionInfo> majorsWithEnrollmentPlan = majors.stream()
                    .filter(major -> major.getEnrollmentPlanData() != null && !major.getEnrollmentPlanData().isEmpty())
                    .collect(Collectors.toList());

            if (!majorsWithEnrollmentPlan.isEmpty()) {
                log.info("开始为 {} 个有招生计划的专业查询近三年录取分数线数据", majorsWithEnrollmentPlan.size());
                batchQueryThreeYearsAdmissionScores(majorsWithEnrollmentPlan, profile);
                log.info("近三年录取分数线数据查询完成");
            } else {
                log.info("没有专业有招生计划数据，跳过录取分数线查询");
            }

        } catch (Exception e) {
            log.error("批量查询近三年招生计划数据失败（V2优化版本）", e);
        }
    }

    /**
     * 获取可填专业数据 - 专门为前端设计的简化接口
     * 基于 getSchoolGroupedMajorsOptimized 方法，但返回更适合前端的数据格式
     */
    public SuitableMajorsRespVO getSuitableMajorsForFrontend(UserProfileInfo profile,
                                                            Integer pageNo,
                                                            Integer pageSize,
                                                            List<String> levelTypes,
                                                            Boolean includeMajorDetails,
                                                            String targetSchoolUuid) {
        long startTime = System.currentTimeMillis();
        log.info("开始获取可填专业数据（前端专用接口），页码：{}，每页：{}，请求等级：{}",
                pageNo, pageSize, levelTypes);

        SuitableMajorsRespVO result = new SuitableMajorsRespVO();

        try {
            // 调用现有的优化方法获取数据
            DirectParamsGroupRespVO groupResult = getSchoolGroupedMajorsOptimized(
                    profile, pageNo, pageSize, levelTypes, includeMajorDetails, targetSchoolUuid);

            // 转换为前端专用的响应格式
            if (groupResult.getSchoolGroups() != null) {
                // 转换学校分组数据
                List<SuitableMajorsRespVO.SchoolMajorData> schoolMajors = groupResult.getSchoolGroups().getList()
                        .stream()
                        .map(this::convertToSchoolMajorData)
                        .collect(Collectors.toList());

                PageResult<SuitableMajorsRespVO.SchoolMajorData> pageResult =
                        new PageResult<>(schoolMajors, groupResult.getSchoolGroups().getTotal());
                result.setSchoolMajors(pageResult);
            }

            // 转换统计数据
            if (groupResult.getSchoolClassification() != null) {
                SuitableMajorsRespVO.ClassificationSummary summary = new SuitableMajorsRespVO.ClassificationSummary();
                summary.setRushSchoolCount(groupResult.getSchoolClassification().getRushCount());
                summary.setStableSchoolCount(groupResult.getSchoolClassification().getStableCount());
                summary.setSafeSchoolCount(groupResult.getSchoolClassification().getSafeCount());
                summary.setTotalSchoolCount(groupResult.getSchoolClassification().getTotalCount());

                // 计算专业数量统计（从学校数据中汇总）
                if (groupResult.getSchoolGroups() != null) {
                    int rushMajorCount = groupResult.getSchoolGroups().getList().stream()
                            .mapToInt(school -> school.getRushCount() != null ? school.getRushCount() : 0)
                            .sum();
                    int stableMajorCount = groupResult.getSchoolGroups().getList().stream()
                            .mapToInt(school -> school.getStableCount() != null ? school.getStableCount() : 0)
                            .sum();
                    int safeMajorCount = groupResult.getSchoolGroups().getList().stream()
                            .mapToInt(school -> school.getSafeCount() != null ? school.getSafeCount() : 0)
                            .sum();

                    summary.setRushMajorCount(rushMajorCount);
                    summary.setStableMajorCount(stableMajorCount);
                    summary.setSafeMajorCount(safeMajorCount);
                    summary.setTotalMajorCount(rushMajorCount + stableMajorCount + safeMajorCount);
                }

                result.setSummary(summary);
            }

            result.setQueryInfo(groupResult.getQueryInfo());

            long endTime = System.currentTimeMillis();
            log.info("获取可填专业数据完成（前端专用接口），耗时：{}ms", endTime - startTime);

        } catch (Exception e) {
            log.error("获取可填专业数据失败（前端专用接口）", e);
            result.setQueryInfo("查询过程中发生错误：" + e.getMessage());
        }

        return result;
    }

    /**
     * 转换学校分组数据为前端格式
     */
    private SuitableMajorsRespVO.SchoolMajorData convertToSchoolMajorData(DirectParamsGroupRespVO.SchoolGroupData source) {
        SuitableMajorsRespVO.SchoolMajorData target = new SuitableMajorsRespVO.SchoolMajorData();

        target.setSchoolUuid(source.getSchoolUuid());
        target.setSchoolName(source.getSchoolName());
        target.setLevelType(source.getLevelType());
        target.setRushCount(source.getRushCount());
        target.setStableCount(source.getStableCount());
        target.setSafeCount(source.getSafeCount());
        target.setTotalCount(source.getTotalCount());

        // 转换学校基础信息
        if (source.getSchoolInfo() != null) {
            SuitableMajorsRespVO.SchoolBasicInfo schoolInfo = new SuitableMajorsRespVO.SchoolBasicInfo();
            schoolInfo.setIs985(source.getSchoolInfo().getIs985());
            schoolInfo.setIs211(source.getSchoolInfo().getIs211());
            schoolInfo.setIsDoubleFirstClass(source.getSchoolInfo().getIsDualClass());
            schoolInfo.setProvince(source.getSchoolInfo().getProvince());
            schoolInfo.setCity(source.getSchoolInfo().getCity());
            schoolInfo.setSchoolType(source.getSchoolInfo().getCollegeType());
            target.setSchoolInfo(schoolInfo);
        }

        // 转换专业详细列表
        if (source.getRushMajors() != null || source.getStableMajors() != null || source.getSafeMajors() != null) {
            List<SuitableMajorsRespVO.MajorInfo> majors = new ArrayList<>();

            // 合并所有等级的专业，并设置对应的等级标识
            if (source.getRushMajors() != null) {
                majors.addAll(source.getRushMajors().stream()
                        .map(major -> convertToMajorInfo(major, "rush"))
                        .collect(Collectors.toList()));
            }
            if (source.getStableMajors() != null) {
                majors.addAll(source.getStableMajors().stream()
                        .map(major -> convertToMajorInfo(major, "stable"))
                        .collect(Collectors.toList()));
            }
            if (source.getSafeMajors() != null) {
                majors.addAll(source.getSafeMajors().stream()
                        .map(major -> convertToMajorInfo(major, "safe"))
                        .collect(Collectors.toList()));
            }

            target.setMajors(majors);
        }

        // 转换招生计划统计（从现有字段构建）
        SuitableMajorsRespVO.EnrollmentStats enrollmentStats = new SuitableMajorsRespVO.EnrollmentStats();
        enrollmentStats.setTotalPlan(source.getTotalEnrollmentPlan());

        // 转换分数和位次（从String转为Integer，处理可能的转换异常）
        try {
            if (source.getLowestAdmissionScore() != null) {
                enrollmentStats.setMinScore(Integer.parseInt(source.getLowestAdmissionScore()));
            }
        } catch (NumberFormatException e) {
            log.warn("转换最低录取分数失败: {}", source.getLowestAdmissionScore());
        }

        try {
            if (source.getLowestAdmissionRank() != null) {
                enrollmentStats.setMinRanking(Integer.parseInt(source.getLowestAdmissionRank()));
            }
        } catch (NumberFormatException e) {
            log.warn("转换最低录取位次失败: {}", source.getLowestAdmissionRank());
        }

        target.setEnrollmentStats(enrollmentStats);

        return target;
    }

    /**
     * 转换专业信息为前端格式
     */
    private SuitableMajorsRespVO.MajorInfo convertToMajorInfo(DirectParamsGroupRespVO.MajorAdmissionInfo source, String levelType) {
        SuitableMajorsRespVO.MajorInfo target = new SuitableMajorsRespVO.MajorInfo();

        target.setMajorName(source.getMajorName());
        target.setMajorCode(source.getMajorCode());
        target.setLevelType(levelType);

        // 转换分数字段（从String转为Integer，处理可能的转换异常）
        try {
            if (source.getLowestScore() != null) {
                target.setLowestScore(Integer.parseInt(source.getLowestScore()));
            }
        } catch (NumberFormatException e) {
            log.warn("转换最低分数失败: {}", source.getLowestScore());
        }

        try {
            if (source.getLowestSection() != null) {
                target.setLowestRanking(Integer.parseInt(source.getLowestSection()));
            }
        } catch (NumberFormatException e) {
            log.warn("转换最低位次失败: {}", source.getLowestSection());
        }

        try {
            if (source.getAverageScore() != null) {
                target.setAverageScore(Integer.parseInt(source.getAverageScore()));
            }
        } catch (NumberFormatException e) {
            log.warn("转换平均分数失败: {}", source.getAverageScore());
        }

        try {
            if (source.getHighScore() != null) {
                target.setHighScore(Integer.parseInt(source.getHighScore()));
            }
        } catch (NumberFormatException e) {
            log.warn("转换最高分数失败: {}", source.getHighScore());
        }

        // 从招生计划数据中获取招生计划数
        if (source.getEnrollmentPlanData() != null && !source.getEnrollmentPlanData().isEmpty()) {
            // 取最新年份的招生计划数
            DirectParamsGroupRespVO.CollegeEnrollmentPlanInfo latestPlan = source.getEnrollmentPlanData().get(0);
            target.setEnrollmentPlan(latestPlan.getEnrollmentPlan());
        }

        target.setBatchName(source.getBatchName());

        return target;
    }

    /**
     * 安全将招生人数字符串转换为Integer值
     * 处理横杠"-"等特殊情况
     */
    private Integer parseEnrollmentNumbers(String enrollmentNumbers) {
        if (enrollmentNumbers == null || enrollmentNumbers.trim().isEmpty()) {
            return 0;
        }

        String trimmed = enrollmentNumbers.trim();

        // 如果是横杠或其他非数字字符，返回0
        if ("-".equals(trimmed) || "—".equals(trimmed) || "无".equals(trimmed) || "不限".equals(trimmed)) {
            return 0;
        }

        try {
            return Integer.parseInt(trimmed);
        } catch (NumberFormatException e) {
            log.warn("无法转换招生人数为Integer: value={}", enrollmentNumbers);
            return 0;
        }
    }

    /**
     * 按专业组扩展录取数据
     * 如果同一学校的某个专业符合分数条件，则返回该专业组下的所有专业
     * @param admissionData 已过滤的录取数据
     * @param provinceName 省份名称
     * @param year 年份
     * @param typeName 类型名称
     * @return 扩展后的录取数据
     */
    private List<MajorAdmissionDO> expandAdmissionDataBySpecialGroup(List<MajorAdmissionDO> admissionData, 
                                                                    String provinceName, Integer year, String typeName) {
        if (admissionData == null || admissionData.isEmpty()) {
            return admissionData;
        }

        // 1) 收集当前命中的学校名称与专业名称（用于批量查询招生计划，识别专业组）
        Set<String> schoolNamesSet = new HashSet<>();
        Set<String> majorNamesSet = new HashSet<>();
        for (MajorAdmissionDO admission : admissionData) {
            if (admission.getSchoolName() != null) {
                schoolNamesSet.add(admission.getSchoolName());
            }
            if (admission.getMajorName() != null) {
                majorNamesSet.add(admission.getMajorName());
            }
        }
        
        List<String> schoolNames = new ArrayList<>(schoolNamesSet);
        List<String> majorNames = new ArrayList<>(majorNamesSet);

        if (schoolNames.isEmpty() || majorNames.isEmpty()) {
            log.info("按专业组扩展：学校名称或专业名称为空，跳过扩展");
            return admissionData;
        }

        // 2) 查询招生计划，获取各校专业所属的专业组
        List<CollegeEnrollmentPlanDO> groupPlans = collegeEnrollmentPlanMapper
                .selectExistingEnrollmentPlansWithBracketHandling(schoolNames, majorNames, provinceName, 2025);
        //过滤掉国家专项计划及提前批
        groupPlans = groupPlans.stream()
                .filter(plan -> !plan.getBatchName().contains("国家专项"))
                .filter(plan -> !plan.getBatchName().contains("提前批"))
                .collect(Collectors.toList());

        if (groupPlans == null || groupPlans.isEmpty()) {
            log.info("按专业组扩展：未查询到对应招生计划，跳过扩展");
            return admissionData;
        }

        // 3) 构建专业组映射关系
        // key1: schoolName|majorName -> specialGroup
        Map<String, String> schoolMajorToGroup = new HashMap<>();
        // key2: schoolName|specialGroup -> Set<majorName>（该校此专业组下的所有专业）
        Map<String, Set<String>> schoolGroupToMajors = new HashMap<>();
        
        for (CollegeEnrollmentPlanDO plan : groupPlans) {
            String schoolName = plan.getSchoolName();
            String majorName = plan.getCollegeMajorName();
            String groupCode = plan.getSpecialGroup();
            
            if (schoolName == null || majorName == null || groupCode == null || groupCode.trim().isEmpty()) {
                continue;
            }
            
            schoolMajorToGroup.putIfAbsent(schoolName + "|" + majorName, groupCode);
            String groupKey = schoolName + "|" + groupCode;
            schoolGroupToMajors.computeIfAbsent(groupKey, k -> new LinkedHashSet<>()).add(majorName);
        }

        if (schoolMajorToGroup.isEmpty()) {
            log.info("按专业组扩展：未找到有效的专业组映射关系，跳过扩展");
            return admissionData;
        }

        // 4) 计算每个学校UUID需要扩展的专业（该校内同专业组的所有专业）
        Map<String, Set<String>> schoolUuidToMajorsToFetch = new HashMap<>();
        for (MajorAdmissionDO admission : admissionData) {
            String schoolName = admission.getSchoolName();
            String schoolUuid = admission.getSchoolUuid();
            String majorName = admission.getMajorName();
            
            if (schoolName == null || schoolUuid == null || majorName == null) {
                continue;
            }
            
            String groupCode = schoolMajorToGroup.get(schoolName + "|" + majorName);
            if (groupCode == null) {
                continue;
            }
            
            Set<String> groupMajors = schoolGroupToMajors.get(schoolName + "|" + groupCode);
            if (groupMajors == null || groupMajors.isEmpty()) {
                continue;
            }
            
            schoolUuidToMajorsToFetch.computeIfAbsent(schoolUuid, k -> new LinkedHashSet<>()).addAll(groupMajors);
        }

        if (schoolUuidToMajorsToFetch.isEmpty()) {
            log.info("按专业组扩展：未找到需要扩展的专业，跳过扩展");
            return admissionData;
        }

        // 5) 构建现有键用于去重
        Set<String> existingKeys = new HashSet<>();
        for (MajorAdmissionDO admission : admissionData) {
            String key = buildAdmissionKey(admission);
            existingKeys.add(key);
        }

        // 6) 按学校UUID批量查询需补齐的专业的录取数据（限定省份/年份/类型），并合并
        List<MajorAdmissionDO> extraList = new ArrayList<>();
        for (Map.Entry<String, Set<String>> entry : schoolUuidToMajorsToFetch.entrySet()) {
            String schoolUuid = entry.getKey();
            Set<String> majorsToFetch = entry.getValue();
            
            if (majorsToFetch == null || majorsToFetch.isEmpty()) {
                continue;
            }

            LambdaQueryWrapperX<MajorAdmissionDO> wrapper = new LambdaQueryWrapperX<>();
            if (year != null) {
                wrapper.eq(MajorAdmissionDO::getYear, year);
            }
            if (provinceName != null && !provinceName.trim().isEmpty()) {
                wrapper.eq(MajorAdmissionDO::getProvinceName, provinceName);
            }
            if (typeName != null && !typeName.trim().isEmpty()) {
                wrapper.eq(MajorAdmissionDO::getTypeName, typeName);
            }
            wrapper.eq(MajorAdmissionDO::getSchoolUuid, schoolUuid);
            wrapper.in(MajorAdmissionDO::getMajorName, new ArrayList<>(majorsToFetch));

            List<MajorAdmissionDO> fetched = majorAdmissionMapper.selectList(wrapper);
            if (fetched != null && !fetched.isEmpty()) {
                for (MajorAdmissionDO fetchedAdmission : fetched) {
                    String key = buildAdmissionKey(fetchedAdmission);
                    if (!existingKeys.contains(key)) {
                        extraList.add(fetchedAdmission);
                        existingKeys.add(key);
                    }
                }
            }
        }

        if (!extraList.isEmpty()) {
            // 对补充的专业也进行batchName过滤，过滤掉包含"国家专项"或"本科提前批"的专业
            extraList = filterOutSpecialBatchMajors(extraList);
            
            if (!extraList.isEmpty()) {
                List<MajorAdmissionDO> merged = new ArrayList<>(admissionData.size() + extraList.size());
                merged.addAll(admissionData);
                merged.addAll(extraList);
                log.info("按专业组扩展后，新增补充 {} 条记录，合计 {} 条", extraList.size(), merged.size());
                return merged;
            } else {
                log.info("按专业组扩展的补充专业全部被batchName过滤，未新增记录");
                return admissionData;
            }
        } else {
            log.info("按专业组扩展未新增记录");
            return admissionData;
        }
    }

    /**
     * 构建录取数据的唯一键，用于去重
     */
    private String buildAdmissionKey(MajorAdmissionDO admission) {
        return (admission.getSchoolUuid() == null ? "" : admission.getSchoolUuid()) + "|" +
               (admission.getMajorName() == null ? "" : admission.getMajorName()) + "|" +
               (admission.getYear() == null ? "" : admission.getYear().toString()) + "|" +
               (admission.getBatchName() == null ? "" : admission.getBatchName()) + "|" +
               (admission.getTypeName() == null ? "" : admission.getTypeName());
    }

    /**
     * 过滤掉batchName包含"国家专项"或"本科提前批"的专业
     * @param admissionData 专业录取数据列表
     * @return 过滤后的专业录取数据列表
     */
    private List<MajorAdmissionDO> filterOutSpecialBatchMajors(List<MajorAdmissionDO> admissionData) {
        if (admissionData == null || admissionData.isEmpty()) {
            return admissionData;
        }

        int originalSize = admissionData.size();
        List<MajorAdmissionDO> filteredData = admissionData.stream()
                .filter(admission -> {
                    String batchName = admission.getBatchName();
                    if (batchName == null || batchName.trim().isEmpty()) {
                        return true; // 保留没有批次信息的专业
                    }
                    
                    // 过滤掉包含"国家专项"或"本科提前批"的专业
                    return !batchName.contains("国家专项") && !batchName.contains("本科提前批");
                })
                .collect(Collectors.toList());

        int filteredSize = filteredData.size();
        int removedCount = originalSize - filteredSize;
        
        if (removedCount > 0) {
            log.info("过滤掉包含'国家专项'或'本科提前批'的专业 {} 个，剩余 {} 个专业", removedCount, filteredSize);
        }

        return filteredData;
    }
}
